From 1762cdc9c9b999a6a09829c449f00ff6335ad1c5 Mon Sep 17 00:00:00 2001 From: Timur Doumler Date: Thu, 25 Feb 2016 10:15:21 +0000 Subject: [PATCH] Added runtime permissions request to JUCE Demo (recording tab) and MidiTest example app, added matching permissions to manifest, removed ant exporter, and re-saved both projects. --- .../src/com/juce/jucedemo/JuceDemo.java | 98 +- .../MacOSX/JuceDemo.xcodeproj/project.pbxproj | 12 +- .../Builds/VisualStudio2010/JuceDemo.vcxproj | 7 + .../VisualStudio2010/JuceDemo.vcxproj.filters | 9 + .../Builds/VisualStudio2012/JuceDemo.vcxproj | 7 + .../VisualStudio2012/JuceDemo.vcxproj.filters | 9 + .../Builds/VisualStudio2013/JuceDemo.vcxproj | 7 + .../VisualStudio2013/JuceDemo.vcxproj.filters | 9 + .../Builds/VisualStudio2015/JuceDemo.vcxproj | 7 + .../VisualStudio2015/JuceDemo.vcxproj.filters | 9 + .../iOS/JuceDemo.xcodeproj/project.pbxproj | 6 + examples/Demo/JuceDemo.jucer | 2 +- examples/Demo/Source/MainWindow.cpp | 9 +- .../Builds/Android/AndroidManifest.xml | 21 - examples/MidiTest/Builds/Android/build.xml | 33 - .../MidiTest/Builds/Android/jni/Android.mk | 40 - .../Builds/Android/jni/Application.mk | 13 - .../MidiTest/Builds/Android/local.properties | 10 - .../Builds/Android/project.properties | 5 - .../Builds/Android/res/values/strings.xml | 5 - .../com/yourcompany/miditest/MidiTest.java | 1991 ----------------- .../MacOSX/MidiTest.xcodeproj/project.pbxproj | 28 +- .../Builds/VisualStudio2015/MidiTest.vcxproj | 7 + .../VisualStudio2015/MidiTest.vcxproj.filters | 9 + .../iOS/MidiTest.xcodeproj/project.pbxproj | 10 +- examples/MidiTest/MidiTest.jucer | 36 +- examples/MidiTest/Source/MainComponent.cpp | 4 +- 27 files changed, 239 insertions(+), 2164 deletions(-) delete mode 100644 examples/MidiTest/Builds/Android/AndroidManifest.xml delete mode 100644 examples/MidiTest/Builds/Android/build.xml delete mode 100644 examples/MidiTest/Builds/Android/jni/Android.mk delete mode 100644 examples/MidiTest/Builds/Android/jni/Application.mk delete mode 100644 examples/MidiTest/Builds/Android/local.properties delete mode 100644 examples/MidiTest/Builds/Android/project.properties delete mode 100644 examples/MidiTest/Builds/Android/res/values/strings.xml delete mode 100644 examples/MidiTest/Builds/Android/src/com/yourcompany/miditest/MidiTest.java diff --git a/examples/Demo/Builds/Android/src/com/juce/jucedemo/JuceDemo.java b/examples/Demo/Builds/Android/src/com/juce/jucedemo/JuceDemo.java index 57c1d3a36f..05a78bb2b9 100644 --- a/examples/Demo/Builds/Android/src/com/juce/jucedemo/JuceDemo.java +++ b/examples/Demo/Builds/Android/src/com/juce/jucedemo/JuceDemo.java @@ -30,13 +30,12 @@ import android.content.DialogInterface; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Looper; import android.os.Handler; -import android.os.Build; -import android.os.Process; import android.os.ParcelUuid; import android.os.Environment; import android.view.*; @@ -50,19 +49,16 @@ import android.text.InputType; import android.util.DisplayMetrics; import android.util.Log; import java.lang.Runnable; -import java.util.List; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.TimerTask; +import java.util.*; import java.io.*; import java.net.URL; import java.net.HttpURLConnection; import android.media.AudioManager; import android.media.MediaScannerConnection; import android.media.MediaScannerConnection.MediaScannerConnectionClient; - +import android.support.v4.content.ContextCompat; +import android.support.v4.app.ActivityCompat; +import android.Manifest; import android.media.midi.*; import android.bluetooth.*; @@ -78,6 +74,88 @@ public class JuceDemo extends Activity System.loadLibrary ("juce_jni"); } + //============================================================================== + public boolean isPermissionDeclaredInManifest (int permissionID) + { + String permissionToCheck = getAndroidPermissionName(permissionID); + + try + { + PackageInfo info = getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS); + + if (info.requestedPermissions != null) + for (String permission : info.requestedPermissions) + if (permission.equals (permissionToCheck)) + return true; + } + catch (PackageManager.NameNotFoundException e) + { + Log.d ("JUCE", "isPermissionDeclaredInManifest: PackageManager.NameNotFoundException = " + e.toString()); + } + + Log.d ("JUCE", "isPermissionDeclaredInManifest: could not find requested permission " + permissionToCheck); + return false; + } + + //============================================================================== + // these have to match the values of enum PermissionID in C++ class RuntimePermissions: + private static final int JUCE_PERMISSIONS_RECORD_AUDIO = 1; + private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI= 2; + + private static String getAndroidPermissionName (int permissionID) + { + switch (permissionID) + { + case JUCE_PERMISSIONS_RECORD_AUDIO: return Manifest.permission.RECORD_AUDIO; + case JUCE_PERMISSIONS_BLUETOOTH_MIDI: return Manifest.permission.ACCESS_COARSE_LOCATION; + } + + // unknown permission ID! + assert false; + return new String(); + } + + public boolean isPermissionGranted (int permissionID) + { + return ContextCompat.checkSelfPermission (this, getAndroidPermissionName (permissionID)) == PackageManager.PERMISSION_GRANTED; + } + + private Map permissionCallbackPtrMap; + + public void requestRuntimePermission (int permissionID, long ptrToCallback) + { + permissionCallbackPtrMap.put (permissionID, ptrToCallback); + + String permissionName = getAndroidPermissionName (permissionID); + + if (ContextCompat.checkSelfPermission (this, permissionName) != PackageManager.PERMISSION_GRANTED) + { + ActivityCompat.requestPermissions (this, new String[]{permissionName}, permissionID); + } + } + + private native void androidRuntimePermissionsCallback (boolean permissionWasGranted, long ptrToCallback); + + @Override + public void onRequestPermissionsResult (int permissionID, String permissions[], int[] grantResults) + { + boolean permissionsGranted = (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED); + + if (! permissionsGranted) + Log.d ("JUCE", "onRequestPermissionsResult: runtime permission was DENIED: " + getAndroidPermissionName (permissionID)); + + Long ptrToCallback = permissionCallbackPtrMap.get (permissionID); + permissionCallbackPtrMap.remove (permissionID); + + if (ptrToCallback == null) + { + // something went wrong: we don't have a valid callback pointer to call! + assert false; + return; + } + + androidRuntimePermissionsCallback (permissionsGranted, ptrToCallback); + } //============================================================================== public static class MidiPortID extends Object { @@ -975,6 +1053,8 @@ public class JuceDemo extends Activity setContentView (viewHolder); setVolumeControlStream (AudioManager.STREAM_MUSIC); + + permissionCallbackPtrMap = new HashMap(); } @Override diff --git a/examples/Demo/Builds/MacOSX/JuceDemo.xcodeproj/project.pbxproj b/examples/Demo/Builds/MacOSX/JuceDemo.xcodeproj/project.pbxproj index e1be0e0dba..50211632ae 100644 --- a/examples/Demo/Builds/MacOSX/JuceDemo.xcodeproj/project.pbxproj +++ b/examples/Demo/Builds/MacOSX/JuceDemo.xcodeproj/project.pbxproj @@ -113,6 +113,7 @@ 06AE69217982DB82E0F47554 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AttributedString.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_AttributedString.cpp"; sourceTree = "SOURCE_ROOT"; }; 06B6D19CE5691310DEF50DBC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniserFunctions.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"; sourceTree = "SOURCE_ROOT"; }; 06BD2631BF3C52F26B9981E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_cryptography.h"; path = "../../../../modules/juce_cryptography/juce_cryptography.h"; sourceTree = "SOURCE_ROOT"; }; + 06D514A7B2556A07D2398433 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RuntimePermissions.cpp"; path = "../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"; sourceTree = "SOURCE_ROOT"; }; 06DE336A39A9FEC47A8C2F06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; }; 06FACF171E0DE0AC6318AE4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Message.h"; path = "../../../../modules/juce_events/messages/juce_Message.h"; sourceTree = "SOURCE_ROOT"; }; 0732CB9291291C9854197B28 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Box2D.h; path = "../../../../modules/juce_box2d/box2d/Box2D.h"; sourceTree = "SOURCE_ROOT"; }; @@ -580,6 +581,7 @@ 7890AB8CBF31F9788E10DBD5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentAnimator.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp"; sourceTree = "SOURCE_ROOT"; }; 78979AFF44F164451516C986 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Time.cpp"; path = "../../../../modules/juce_core/time/juce_Time.cpp"; sourceTree = "SOURCE_ROOT"; }; 78B172DD2AAFE3535D0460C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResamplingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 78D08E88D61781FC020AFE3F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_RuntimePermissions.cpp"; path = "../../../../modules/juce_core/native/juce_android_RuntimePermissions.cpp"; sourceTree = "SOURCE_ROOT"; }; 78DAC3299488E0CC70EDB206 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedXLock.h"; path = "../../../../modules/juce_events/native/juce_ScopedXLock.h"; sourceTree = "SOURCE_ROOT"; }; 791B204F13E056DA2644175D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.h"; sourceTree = "SOURCE_ROOT"; }; 79C8D0C6D1444EAB781C46F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -982,6 +984,7 @@ E5058DD199CEC42ECE922239 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Justification.h"; path = "../../../../modules/juce_graphics/placement/juce_Justification.h"; sourceTree = "SOURCE_ROOT"; }; E52756E1DB553ED02D829F61 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_cryptography/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; E6333272C33612B6A7D6073E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDBurner.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp"; sourceTree = "SOURCE_ROOT"; }; + E682A3A52BD15D5CA4933C12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; E6E0ADA4E3632540A8ADC7D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConnectedChildProcess.cpp"; path = "../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; E6E0FE3CBDBE2554B527CF60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSourcePlayer.cpp"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp"; sourceTree = "SOURCE_ROOT"; }; E70A283A87989F5A1CEDE6A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResamplingAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -990,16 +993,15 @@ E7EA99CD84E1EC598F4984DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Array.h"; path = "../../../../modules/juce_core/containers/juce_Array.h"; sourceTree = "SOURCE_ROOT"; }; E7EE6BDC0E3A0739529AED91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSubsectionReader.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"; sourceTree = "SOURCE_ROOT"; }; E80CA3836329ED0EEC74BAE6 = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; }; + E8B785D8DD9C49BC7FF5EA75 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_linux.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_linux.h"; sourceTree = "SOURCE_ROOT"; }; + E8DBB02B17A6E144D08E4CC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Matrix3D.h"; path = "../../../../modules/juce_opengl/geometry/juce_Matrix3D.h"; sourceTree = "SOURCE_ROOT"; }; EACCBFA17F4D07ECE058EEBB = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; }; 229D2DAADACF15540C3BBD15 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JuceDemo.app; sourceTree = "BUILT_PRODUCTS_DIR"; }; DEE5EFE8148FD2DC743A7DD7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LookAndFeelDemo.cpp; path = ../../Source/Demos/LookAndFeelDemo.cpp; sourceTree = "SOURCE_ROOT"; }; E5E02A3C4E942105FEDCA885 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChannelRemappingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - E682A3A52BD15D5CA4933C12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; E7B21011F93915ADD2CC5DD9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; }; E8128A35828C860977FEC54C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatWriter.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"; sourceTree = "SOURCE_ROOT"; }; - E8B785D8DD9C49BC7FF5EA75 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_linux.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_linux.h"; sourceTree = "SOURCE_ROOT"; }; E8D96BDC76CD02DF3E238A88 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tile_background.png"; path = "../../Resources/tile_background.png"; sourceTree = "SOURCE_ROOT"; }; - E8DBB02B17A6E144D08E4CC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Matrix3D.h"; path = "../../../../modules/juce_opengl/geometry/juce_Matrix3D.h"; sourceTree = "SOURCE_ROOT"; }; E98EA1189613978EA4E78D85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentListener.h"; path = "../../../../modules/juce_gui_basics/components/juce_ComponentListener.h"; sourceTree = "SOURCE_ROOT"; }; E9A3E96E32C301EE817059C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SliderPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; E9B8B3FAECC80B66257B14F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BlowFish.h"; path = "../../../../modules/juce_cryptography/encryption/juce_BlowFish.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1050,6 +1052,7 @@ F746F30147C6BE88F60E92CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JSON.cpp"; path = "../../../../modules/juce_core/javascript/juce_JSON.cpp"; sourceTree = "SOURCE_ROOT"; }; F753A7C2031832BB628CBB2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_ALSA.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp"; sourceTree = "SOURCE_ROOT"; }; F779C79AC37C83A60B997641 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandInfo.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp"; sourceTree = "SOURCE_ROOT"; }; + F7CDE069A32CA0EAD1BE7D43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RuntimePermissions.h"; path = "../../../../modules/juce_core/misc/juce_RuntimePermissions.h"; sourceTree = "SOURCE_ROOT"; }; F843FC09B4C2A10C76D8D35C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDirectoryScanner.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp"; sourceTree = "SOURCE_ROOT"; }; F881704607DB79F9A3CF7491 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Audio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; F89584972F16A8EC49E5E74D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinatePositioner.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1595,6 +1598,8 @@ 6C6F5F4F0570E2CE9AA515B7 = {isa = PBXGroup; children = ( 55273A59F96B3C775EB71FAB, 44F4A9351C2B03F98A0D23E4, + 06D514A7B2556A07D2398433, + F7CDE069A32CA0EAD1BE7D43, 4A2C25FD55809F1489963FC3, 360291D0346F776DDD3F43E8, 28E65398C8CF95EB12A5734D, ); name = misc; sourceTree = ""; }; @@ -1603,6 +1608,7 @@ B63933880C456903722F46A4, 60B755F5684959E78C556810, B97B2C0C6A4322FFAACE1C39, + 78D08E88D61781FC020AFE3F, 4290825CEF87C19A113CA9F9, 3CF67E6BCC6B52EFD6E6A458, FA8B6B0F6D43146BAAE04D4D, diff --git a/examples/Demo/Builds/VisualStudio2010/JuceDemo.vcxproj b/examples/Demo/Builds/VisualStudio2010/JuceDemo.vcxproj index 3d48dfd3a5..aae7637c1d 100644 --- a/examples/Demo/Builds/VisualStudio2010/JuceDemo.vcxproj +++ b/examples/Demo/Builds/VisualStudio2010/JuceDemo.vcxproj @@ -628,6 +628,9 @@ true + + true + true @@ -640,6 +643,9 @@ true + + true + true @@ -1573,6 +1579,7 @@ + diff --git a/examples/Demo/Builds/VisualStudio2010/JuceDemo.vcxproj.filters b/examples/Demo/Builds/VisualStudio2010/JuceDemo.vcxproj.filters index 0af39d0b1b..b6020864dc 100644 --- a/examples/Demo/Builds/VisualStudio2010/JuceDemo.vcxproj.filters +++ b/examples/Demo/Builds/VisualStudio2010/JuceDemo.vcxproj.filters @@ -934,6 +934,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc @@ -946,6 +949,9 @@ Juce Modules\juce_core\native + + Juce Modules\juce_core\native + Juce Modules\juce_core\native @@ -2421,6 +2427,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc diff --git a/examples/Demo/Builds/VisualStudio2012/JuceDemo.vcxproj b/examples/Demo/Builds/VisualStudio2012/JuceDemo.vcxproj index fa8bf45a1b..604fff6efd 100644 --- a/examples/Demo/Builds/VisualStudio2012/JuceDemo.vcxproj +++ b/examples/Demo/Builds/VisualStudio2012/JuceDemo.vcxproj @@ -634,6 +634,9 @@ true + + true + true @@ -646,6 +649,9 @@ true + + true + true @@ -1579,6 +1585,7 @@ + diff --git a/examples/Demo/Builds/VisualStudio2012/JuceDemo.vcxproj.filters b/examples/Demo/Builds/VisualStudio2012/JuceDemo.vcxproj.filters index 0af39d0b1b..b6020864dc 100644 --- a/examples/Demo/Builds/VisualStudio2012/JuceDemo.vcxproj.filters +++ b/examples/Demo/Builds/VisualStudio2012/JuceDemo.vcxproj.filters @@ -934,6 +934,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc @@ -946,6 +949,9 @@ Juce Modules\juce_core\native + + Juce Modules\juce_core\native + Juce Modules\juce_core\native @@ -2421,6 +2427,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc diff --git a/examples/Demo/Builds/VisualStudio2013/JuceDemo.vcxproj b/examples/Demo/Builds/VisualStudio2013/JuceDemo.vcxproj index 32441b0bfe..d0fb4e20f1 100644 --- a/examples/Demo/Builds/VisualStudio2013/JuceDemo.vcxproj +++ b/examples/Demo/Builds/VisualStudio2013/JuceDemo.vcxproj @@ -634,6 +634,9 @@ true + + true + true @@ -646,6 +649,9 @@ true + + true + true @@ -1579,6 +1585,7 @@ + diff --git a/examples/Demo/Builds/VisualStudio2013/JuceDemo.vcxproj.filters b/examples/Demo/Builds/VisualStudio2013/JuceDemo.vcxproj.filters index 8ad4d5475a..360f3ada6e 100644 --- a/examples/Demo/Builds/VisualStudio2013/JuceDemo.vcxproj.filters +++ b/examples/Demo/Builds/VisualStudio2013/JuceDemo.vcxproj.filters @@ -934,6 +934,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc @@ -946,6 +949,9 @@ Juce Modules\juce_core\native + + Juce Modules\juce_core\native + Juce Modules\juce_core\native @@ -2421,6 +2427,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc diff --git a/examples/Demo/Builds/VisualStudio2015/JuceDemo.vcxproj b/examples/Demo/Builds/VisualStudio2015/JuceDemo.vcxproj index 455f4e7625..57379f6306 100644 --- a/examples/Demo/Builds/VisualStudio2015/JuceDemo.vcxproj +++ b/examples/Demo/Builds/VisualStudio2015/JuceDemo.vcxproj @@ -634,6 +634,9 @@ true + + true + true @@ -646,6 +649,9 @@ true + + true + true @@ -1579,6 +1585,7 @@ + diff --git a/examples/Demo/Builds/VisualStudio2015/JuceDemo.vcxproj.filters b/examples/Demo/Builds/VisualStudio2015/JuceDemo.vcxproj.filters index 7d5484f967..36a630fa39 100644 --- a/examples/Demo/Builds/VisualStudio2015/JuceDemo.vcxproj.filters +++ b/examples/Demo/Builds/VisualStudio2015/JuceDemo.vcxproj.filters @@ -934,6 +934,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc @@ -946,6 +949,9 @@ Juce Modules\juce_core\native + + Juce Modules\juce_core\native + Juce Modules\juce_core\native @@ -2421,6 +2427,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc diff --git a/examples/Demo/Builds/iOS/JuceDemo.xcodeproj/project.pbxproj b/examples/Demo/Builds/iOS/JuceDemo.xcodeproj/project.pbxproj index 9ccd9a809e..2b8796491d 100644 --- a/examples/Demo/Builds/iOS/JuceDemo.xcodeproj/project.pbxproj +++ b/examples/Demo/Builds/iOS/JuceDemo.xcodeproj/project.pbxproj @@ -111,6 +111,7 @@ 06AE69217982DB82E0F47554 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AttributedString.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_AttributedString.cpp"; sourceTree = "SOURCE_ROOT"; }; 06B6D19CE5691310DEF50DBC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniserFunctions.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"; sourceTree = "SOURCE_ROOT"; }; 06BD2631BF3C52F26B9981E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_cryptography.h"; path = "../../../../modules/juce_cryptography/juce_cryptography.h"; sourceTree = "SOURCE_ROOT"; }; + 06D514A7B2556A07D2398433 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RuntimePermissions.cpp"; path = "../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"; sourceTree = "SOURCE_ROOT"; }; 06DE336A39A9FEC47A8C2F06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; }; 06FACF171E0DE0AC6318AE4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Message.h"; path = "../../../../modules/juce_events/messages/juce_Message.h"; sourceTree = "SOURCE_ROOT"; }; 0732CB9291291C9854197B28 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Box2D.h; path = "../../../../modules/juce_box2d/box2d/Box2D.h"; sourceTree = "SOURCE_ROOT"; }; @@ -578,6 +579,7 @@ 7890AB8CBF31F9788E10DBD5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentAnimator.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp"; sourceTree = "SOURCE_ROOT"; }; 78979AFF44F164451516C986 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Time.cpp"; path = "../../../../modules/juce_core/time/juce_Time.cpp"; sourceTree = "SOURCE_ROOT"; }; 78B172DD2AAFE3535D0460C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResamplingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 78D08E88D61781FC020AFE3F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_RuntimePermissions.cpp"; path = "../../../../modules/juce_core/native/juce_android_RuntimePermissions.cpp"; sourceTree = "SOURCE_ROOT"; }; 78DAC3299488E0CC70EDB206 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedXLock.h"; path = "../../../../modules/juce_events/native/juce_ScopedXLock.h"; sourceTree = "SOURCE_ROOT"; }; 791B204F13E056DA2644175D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.h"; sourceTree = "SOURCE_ROOT"; }; 79C8D0C6D1444EAB781C46F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1057,6 +1059,7 @@ FB8BE0538AD9420DD4D1E9C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiKeyboardState.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp"; sourceTree = "SOURCE_ROOT"; }; FBCD860CD7113A3136B127C8 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; 229D2DAADACF15540C3BBD15 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JuceDemo.app; sourceTree = "BUILT_PRODUCTS_DIR"; }; + F7CDE069A32CA0EAD1BE7D43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RuntimePermissions.h"; path = "../../../../modules/juce_core/misc/juce_RuntimePermissions.h"; sourceTree = "SOURCE_ROOT"; }; F97F775EDCD2D1C497625D4F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Fonts.mm"; path = "../../../../modules/juce_graphics/native/juce_mac_Fonts.mm"; sourceTree = "SOURCE_ROOT"; }; F9F4D5D9783B88F2DE889023 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SubregionStream.h"; path = "../../../../modules/juce_core/streams/juce_SubregionStream.h"; sourceTree = "SOURCE_ROOT"; }; FA5777F9FFCC6BE9D9F98874 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Desktop.h"; path = "../../../../modules/juce_gui_basics/components/juce_Desktop.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1593,6 +1596,8 @@ 6C6F5F4F0570E2CE9AA515B7 = {isa = PBXGroup; children = ( 55273A59F96B3C775EB71FAB, 44F4A9351C2B03F98A0D23E4, + 06D514A7B2556A07D2398433, + F7CDE069A32CA0EAD1BE7D43, 4A2C25FD55809F1489963FC3, 360291D0346F776DDD3F43E8, 28E65398C8CF95EB12A5734D, ); name = misc; sourceTree = ""; }; @@ -1601,6 +1606,7 @@ B63933880C456903722F46A4, 60B755F5684959E78C556810, B97B2C0C6A4322FFAACE1C39, + 78D08E88D61781FC020AFE3F, 4290825CEF87C19A113CA9F9, 3CF67E6BCC6B52EFD6E6A458, FA8B6B0F6D43146BAAE04D4D, diff --git a/examples/Demo/JuceDemo.jucer b/examples/Demo/JuceDemo.jucer index 9da17b250f..6b5065fbc3 100644 --- a/examples/Demo/JuceDemo.jucer +++ b/examples/Demo/JuceDemo.jucer @@ -203,7 +203,7 @@ androidKeyStorePass="android" androidKeyAlias="androiddebugkey" androidKeyAliasPass="android" androidCpp11="1" targetFolder="Builds/AndroidStudio" androidSDKPath="" androidNDKPath="" androidBluetoothNeeded="1" - bigIcon="BvyE0d" androidScreenOrientation="unspecified"> + bigIcon="BvyE0d" androidScreenOrientation="unspecified" androidMicNeeded="1"> diff --git a/examples/Demo/Source/MainWindow.cpp b/examples/Demo/Source/MainWindow.cpp index 2dd84a4163..e3f29ceed9 100644 --- a/examples/Demo/Source/MainWindow.cpp +++ b/examples/Demo/Source/MainWindow.cpp @@ -558,7 +558,14 @@ AudioDeviceManager& MainAppWindow::getSharedAudioDeviceManager() if (sharedAudioDeviceManager == nullptr) { sharedAudioDeviceManager = new AudioDeviceManager(); - sharedAudioDeviceManager->initialise (2, 2, 0, true, String(), 0); + + RuntimePermissions::request ( + RuntimePermissions::recordAudio, + [&] (bool wasGranted) { + int numInputChannels = wasGranted ? 2 : 0; + sharedAudioDeviceManager->initialise (numInputChannels, 2, nullptr, true, String(), nullptr); + } + ); } return *sharedAudioDeviceManager; diff --git a/examples/MidiTest/Builds/Android/AndroidManifest.xml b/examples/MidiTest/Builds/Android/AndroidManifest.xml deleted file mode 100644 index b4a07be084..0000000000 --- a/examples/MidiTest/Builds/Android/AndroidManifest.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/examples/MidiTest/Builds/Android/build.xml b/examples/MidiTest/Builds/Android/build.xml deleted file mode 100644 index a135db96e2..0000000000 --- a/examples/MidiTest/Builds/Android/build.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/MidiTest/Builds/Android/jni/Android.mk b/examples/MidiTest/Builds/Android/jni/Android.mk deleted file mode 100644 index a167d4a65c..0000000000 --- a/examples/MidiTest/Builds/Android/jni/Android.mk +++ /dev/null @@ -1,40 +0,0 @@ -# Automatically generated makefile, created by the Introjucer -# Don't edit this file! Your changes will be overwritten when you re-save the Introjucer project! - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -ifeq ($(TARGET_ARCH_ABI), armeabi-v7a) - LOCAL_ARM_MODE := arm -endif - -LOCAL_MODULE := juce_jni -LOCAL_SRC_FILES := \ - ../../../Source/Main.cpp\ - ../../../Source/MainComponent.cpp\ - ../../../../../modules/juce_audio_basics/juce_audio_basics.cpp\ - ../../../../../modules/juce_audio_devices/juce_audio_devices.cpp\ - ../../../../../modules/juce_audio_formats/juce_audio_formats.cpp\ - ../../../../../modules/juce_audio_processors/juce_audio_processors.cpp\ - ../../../../../modules/juce_audio_utils/juce_audio_utils.cpp\ - ../../../../../modules/juce_core/juce_core.cpp\ - ../../../../../modules/juce_data_structures/juce_data_structures.cpp\ - ../../../../../modules/juce_events/juce_events.cpp\ - ../../../../../modules/juce_graphics/juce_graphics.cpp\ - ../../../../../modules/juce_gui_basics/juce_gui_basics.cpp\ - ../../../../../modules/juce_gui_extra/juce_gui_extra.cpp\ - -ifeq ($(NDK_DEBUG),1) - LOCAL_CPPFLAGS += -fsigned-char -fexceptions -frtti -g -I "../../JuceLibraryCode" -I "../../../../modules" -O0 -std=c++11 -std=gnu++11 -D "JUCE_ANDROID=1" -D "JUCE_ANDROID_API_VERSION=23" -D "JUCE_ANDROID_ACTIVITY_CLASSNAME=com_yourcompany_miditest_MidiTest" -D JUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/yourcompany/miditest/MidiTest\" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_ANDROID_7F0E4A25=1" -D "JUCE_APP_VERSION=1.0.0" -D "JUCE_APP_VERSION_HEX=0x10000" - LOCAL_LDLIBS := -llog -lGLESv2 -landroid -lEGL - LOCAL_CFLAGS += -fsigned-char -fexceptions -frtti -g -I "../../JuceLibraryCode" -I "../../../../modules" -O0 -std=c++11 -std=gnu++11 -D "JUCE_ANDROID=1" -D "JUCE_ANDROID_API_VERSION=23" -D "JUCE_ANDROID_ACTIVITY_CLASSNAME=com_yourcompany_miditest_MidiTest" -D JUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/yourcompany/miditest/MidiTest\" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_ANDROID_7F0E4A25=1" -D "JUCE_APP_VERSION=1.0.0" -D "JUCE_APP_VERSION_HEX=0x10000" - LOCAL_LDLIBS := -llog -lGLESv2 -landroid -lEGL -else - LOCAL_CPPFLAGS += -fsigned-char -fexceptions -frtti -I "../../JuceLibraryCode" -I "../../../../modules" -O3 -std=c++11 -std=gnu++11 -D "JUCE_ANDROID=1" -D "JUCE_ANDROID_API_VERSION=23" -D "JUCE_ANDROID_ACTIVITY_CLASSNAME=com_yourcompany_miditest_MidiTest" -D JUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/yourcompany/miditest/MidiTest\" -D "NDEBUG=1" -D "JUCER_ANDROID_7F0E4A25=1" -D "JUCE_APP_VERSION=1.0.0" -D "JUCE_APP_VERSION_HEX=0x10000" - LOCAL_LDLIBS := -llog -lGLESv2 -landroid -lEGL - LOCAL_CFLAGS += -fsigned-char -fexceptions -frtti -I "../../JuceLibraryCode" -I "../../../../modules" -O3 -std=c++11 -std=gnu++11 -D "JUCE_ANDROID=1" -D "JUCE_ANDROID_API_VERSION=23" -D "JUCE_ANDROID_ACTIVITY_CLASSNAME=com_yourcompany_miditest_MidiTest" -D JUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/yourcompany/miditest/MidiTest\" -D "NDEBUG=1" -D "JUCER_ANDROID_7F0E4A25=1" -D "JUCE_APP_VERSION=1.0.0" -D "JUCE_APP_VERSION_HEX=0x10000" - LOCAL_LDLIBS := -llog -lGLESv2 -landroid -lEGL -endif - -include $(BUILD_SHARED_LIBRARY) diff --git a/examples/MidiTest/Builds/Android/jni/Application.mk b/examples/MidiTest/Builds/Android/jni/Application.mk deleted file mode 100644 index 0821be1887..0000000000 --- a/examples/MidiTest/Builds/Android/jni/Application.mk +++ /dev/null @@ -1,13 +0,0 @@ -# Automatically generated makefile, created by the Introjucer -# Don't edit this file! Your changes will be overwritten when you re-save the Introjucer project! - -APP_STL := gnustl_static -APP_CPPFLAGS += -fsigned-char -fexceptions -frtti -Wno-psabi -APP_PLATFORM := android-23 -NDK_TOOLCHAIN_VERSION := 4.8 - -ifeq ($(NDK_DEBUG),1) - APP_ABI := armeabi-v7a -else - APP_ABI := armeabi-v7a -endif diff --git a/examples/MidiTest/Builds/Android/local.properties b/examples/MidiTest/Builds/Android/local.properties deleted file mode 100644 index 45d3a8b7ad..0000000000 --- a/examples/MidiTest/Builds/Android/local.properties +++ /dev/null @@ -1,10 +0,0 @@ -# This file is used to override default values used by the Ant build system. -# It is automatically generated by the Introjucer - DO NOT EDIT IT or your changes will be lost!. - -sdk.dir=${user.home}/Library/Android/sdk -ndk.dir=${user.home}/Library/Android/sdk/ndk-bundle -key.store=${user.home}/.android/debug.keystore -key.alias=androiddebugkey -key.store.password=android -key.alias.password=android - diff --git a/examples/MidiTest/Builds/Android/project.properties b/examples/MidiTest/Builds/Android/project.properties deleted file mode 100644 index c05f8f091b..0000000000 --- a/examples/MidiTest/Builds/Android/project.properties +++ /dev/null @@ -1,5 +0,0 @@ -# This file is used to override default values used by the Ant build system. -# It is automatically generated - DO NOT EDIT IT or your changes will be lost!. - -target=android-23 - diff --git a/examples/MidiTest/Builds/Android/res/values/strings.xml b/examples/MidiTest/Builds/Android/res/values/strings.xml deleted file mode 100644 index ceb2d0f356..0000000000 --- a/examples/MidiTest/Builds/Android/res/values/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - MidiTest - diff --git a/examples/MidiTest/Builds/Android/src/com/yourcompany/miditest/MidiTest.java b/examples/MidiTest/Builds/Android/src/com/yourcompany/miditest/MidiTest.java deleted file mode 100644 index cf2ee7e2e7..0000000000 --- a/examples/MidiTest/Builds/Android/src/com/yourcompany/miditest/MidiTest.java +++ /dev/null @@ -1,1991 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -package com.yourcompany.miditest; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.Looper; -import android.os.Handler; -import android.os.Build; -import android.os.Process; -import android.os.ParcelUuid; -import android.os.Environment; -import android.view.*; -import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.graphics.*; -import android.text.ClipboardManager; -import android.text.InputType; -import android.util.DisplayMetrics; -import android.util.Log; -import java.lang.Runnable; -import java.util.List; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.TimerTask; -import java.io.*; -import java.net.URL; -import java.net.HttpURLConnection; -import android.media.AudioManager; -import android.media.MediaScannerConnection; -import android.media.MediaScannerConnection.MediaScannerConnectionClient; - - -import android.media.midi.*; -import android.bluetooth.*; -import android.bluetooth.le.*; - - -//============================================================================== -public class MidiTest extends Activity -{ - //============================================================================== - static - { - System.loadLibrary ("juce_jni"); - } - - //============================================================================== - public static class MidiPortID extends Object - { - public MidiPortID (int index, boolean direction) - { - androidIndex = index; - isInput = direction; - } - - public int androidIndex; - public boolean isInput; - - @Override - public int hashCode() - { - Integer i = new Integer (androidIndex); - return i.hashCode() * (isInput ? -1 : 1); - } - - @Override - public boolean equals (Object obj) - { - if (obj == null) - return false; - - if (getClass() != obj.getClass()) - return false; - - MidiPortID other = (MidiPortID) obj; - return (androidIndex == other.androidIndex && isInput == other.isInput); - } - } - - public interface JuceMidiPort - { - boolean isInputPort(); - - // start, stop does nothing on an output port - void start(); - void stop(); - - void close(); - MidiPortID getPortId(); - - // send will do nothing on an input port - void sendMidi (byte[] msg, int offset, int count); - } - - //============================================================================== - //============================================================================== - public class BluetoothManager extends ScanCallback - { - BluetoothManager() - { - ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder(); - scanFilterBuilder.setServiceUuid (ParcelUuid.fromString (bluetoothLEMidiServiceUUID)); - - ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder(); - scanSettingsBuilder.setCallbackType (ScanSettings.CALLBACK_TYPE_ALL_MATCHES) - .setScanMode (ScanSettings.SCAN_MODE_LOW_POWER) - .setScanMode (ScanSettings.MATCH_MODE_STICKY); - - BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - - if (bluetoothAdapter == null) - { - Log.d ("JUCE", "BluetoothManager error: could not get default Bluetooth adapter"); - return; - } - - BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); - - if (bluetoothLeScanner == null) - { - Log.d ("JUCE", "BluetoothManager error: could not get Bluetooth LE scanner"); - return; - } - - bluetoothLeScanner.startScan (Arrays.asList (scanFilterBuilder.build()), - scanSettingsBuilder.build(), - this); - } - - public String[] getMidiBluetoothAddresses() - { - return bluetoothMidiDevices.toArray (new String[bluetoothMidiDevices.size()]); - } - - public String getHumanReadableStringForBluetoothAddress (String address) - { - BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice (address); - return btDevice.getName(); - } - - public boolean isBluetoothDevicePaired (String address) - { - return getAndroidMidiDeviceManager().isBluetoothDevicePaired (address); - } - - public boolean pairBluetoothMidiDevice(String address) - { - BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice (address); - - if (btDevice == null) - { - Log.d ("JUCE", "failed to create buletooth device from address"); - return false; - } - - MidiManager mm = (MidiManager) getSystemService (MIDI_SERVICE); - - PhysicalMidiDevice midiDevice = PhysicalMidiDevice.fromBluetoothLeDevice (btDevice, mm); - - if (midiDevice != null) - { - getAndroidMidiDeviceManager().addDeviceToList (midiDevice); - return true; - } - - return false; - } - - public void unpairBluetoothMidiDevice (String address) - { - getAndroidMidiDeviceManager().unpairBluetoothDevice (address); - } - - public void onScanFailed (int errorCode) - { - } - - public void onScanResult (int callbackType, ScanResult result) - { - if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES - || callbackType == ScanSettings.CALLBACK_TYPE_FIRST_MATCH) - { - BluetoothDevice device = result.getDevice(); - - if (device != null) - bluetoothMidiDevices.add (device.getAddress()); - } - - if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) - { - Log.d ("JUCE", "ScanSettings.CALLBACK_TYPE_MATCH_LOST"); - BluetoothDevice device = result.getDevice(); - - if (device != null) - { - bluetoothMidiDevices.remove (device.getAddress()); - unpairBluetoothMidiDevice (device.getAddress()); - } - } - } - - public void onBatchScanResults (List results) - { - for (ScanResult result : results) - onScanResult (ScanSettings.CALLBACK_TYPE_ALL_MATCHES, result); - } - - private BluetoothLeScanner scanner; - private static final String bluetoothLEMidiServiceUUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700"; - - private HashSet bluetoothMidiDevices = new HashSet(); - } - - public static class JuceMidiInputPort extends MidiReceiver implements JuceMidiPort - { - private native void handleReceive (long host, byte[] msg, int offset, int count, long timestamp); - - public JuceMidiInputPort (PhysicalMidiDevice device, long host, MidiOutputPort midiPort) - { - parent = device; - juceHost = host; - port = midiPort; - } - - @Override - public boolean isInputPort() - { - return true; - } - - @Override - public void start() - { - port.connect (this); - } - - @Override - public void stop() - { - port.disconnect (this); - } - - @Override - public void close() - { - stop(); - - try - { - port.close(); - } - catch (IOException e) - { - Log.d ("JUCE", "JuceMidiInputPort::close: IOException = " + e.toString()); - } - - if (parent != null) - { - parent.removePort (port.getPortNumber(), true); - parent = null; - } - } - - public void onSend (byte[] msg, int offset, int count, long timestamp) - { - if (count > 0) - handleReceive (juceHost, msg, offset, count, timestamp); - } - - @Override - public MidiPortID getPortId() - { - return new MidiPortID (port.getPortNumber(), true); - } - - @Override - public void sendMidi (byte[] msg, int offset, int count) - { - } - - private PhysicalMidiDevice parent = null; - private long juceHost = 0; - private MidiOutputPort port; - } - - public static class JuceMidiOutputPort implements JuceMidiPort - { - public JuceMidiOutputPort (PhysicalMidiDevice device, MidiInputPort midiPort) - { - parent = device; - port = midiPort; - } - - @Override - public boolean isInputPort() - { - return false; - } - - @Override - public void start() - { - } - - @Override - public void stop() - { - } - - @Override - public void sendMidi (byte[] msg, int offset, int count) - { - try - { - port.send(msg, offset, count); - } - catch (IOException e) - { - Log.d ("JUCE", "JuceMidiOutputPort::sendMidi: IOException = " + e.toString()); - } - } - - @Override - public void close() - { - try - { - port.close(); - } - catch (IOException e) - { - Log.d ("JUCE", "JuceMidiOutputPort::close: IOException = " + e.toString()); - } - - if (parent != null) - { - parent.removePort (port.getPortNumber(), false); - parent = null; - } - } - - - @Override - public MidiPortID getPortId() - { - return new MidiPortID (port.getPortNumber(), false); - } - - private PhysicalMidiDevice parent = null; - private MidiInputPort port; - } - - public static class PhysicalMidiDevice - { - private static class MidiDeviceThread extends Thread - { - public Handler handler = null; - public Object sync = null; - - public MidiDeviceThread (Object syncrhonization) - { - sync = syncrhonization; - } - - public void run() - { - Looper.prepare(); - - synchronized (sync) - { - handler = new Handler(); - sync.notifyAll(); - } - - Looper.loop(); - } - } - - private static class MidiDeviceOpenCallback implements MidiManager.OnDeviceOpenedListener - { - public Object sync = null; - public boolean isWaiting = true; - public android.media.midi.MidiDevice theDevice = null; - - public MidiDeviceOpenCallback (Object waiter) - { - sync = waiter; - } - - public void onDeviceOpened (MidiDevice device) - { - synchronized (sync) - { - theDevice = device; - isWaiting = false; - sync.notifyAll(); - } - } - } - - public static PhysicalMidiDevice fromBluetoothLeDevice (BluetoothDevice bluetoothDevice, MidiManager mm) - { - Object waitForCreation = new Object(); - MidiDeviceThread thread = new MidiDeviceThread (waitForCreation); - thread.start(); - - synchronized (waitForCreation) - { - while (thread.handler == null) - { - try - { - waitForCreation.wait(); - } - catch (InterruptedException e) - { - Log.d ("JUCE", "Wait was interrupted but we don't care"); - } - } - } - - Object waitForDevice = new Object(); - - MidiDeviceOpenCallback openCallback = new MidiDeviceOpenCallback (waitForDevice); - - synchronized (waitForDevice) - { - mm.openBluetoothDevice (bluetoothDevice, openCallback, thread.handler); - - while (openCallback.isWaiting) - { - try - { - waitForDevice.wait(); - } - catch (InterruptedException e) - { - Log.d ("JUCE", "Wait was interrupted but we don't care"); - } - } - } - - if (openCallback.theDevice == null) - { - Log.d ("JUCE", "openBluetoothDevice failed"); - return null; - } - - PhysicalMidiDevice device = new PhysicalMidiDevice(); - - device.handle = openCallback.theDevice; - device.info = device.handle.getInfo(); - device.bluetoothAddress = bluetoothDevice.getAddress(); - device.midiManager = mm; - - return device; - } - - public void unpair() - { - if (! bluetoothAddress.equals ("") && handle != null) - { - JuceMidiPort ports[] = new JuceMidiPort[0]; - ports = juceOpenedPorts.values().toArray(ports); - - for (int i = 0; i < ports.length; ++i) - ports[i].close(); - - juceOpenedPorts.clear(); - - try - { - handle.close(); - } - catch (IOException e) - { - Log.d ("JUCE", "handle.close(): IOException = " + e.toString()); - } - - handle = null; - } - } - - public static PhysicalMidiDevice fromMidiDeviceInfo (MidiDeviceInfo info, MidiManager mm) - { - PhysicalMidiDevice device = new PhysicalMidiDevice(); - device.info = info; - device.midiManager = mm; - return device; - } - - public PhysicalMidiDevice() - { - bluetoothAddress = ""; - juceOpenedPorts = new Hashtable(); - handle = null; - } - - public MidiDeviceInfo.PortInfo[] getPorts() - { - return info.getPorts(); - } - - public String getHumanReadableNameForPort (MidiDeviceInfo.PortInfo port, int portIndexToUseInName) - { - String portName = port.getName(); - - if (portName.equals ("")) - portName = ((port.getType() == MidiDeviceInfo.PortInfo.TYPE_OUTPUT) ? "Out " : "In ") - + Integer.toString (portIndexToUseInName); - - return getHumanReadableDeviceName() + " " + portName; - } - - public String getHumanReadableNameForPort (int portType, int androidPortID, int portIndexToUseInName) - { - MidiDeviceInfo.PortInfo[] ports = info.getPorts(); - - for (MidiDeviceInfo.PortInfo port : ports) - { - if (port.getType() == portType) - { - if (port.getPortNumber() == androidPortID) - return getHumanReadableNameForPort (port, portIndexToUseInName); - } - } - - return "Unknown"; - } - - public String getHumanReadableDeviceName() - { - Bundle bundle = info.getProperties(); - return bundle.getString (MidiDeviceInfo.PROPERTY_NAME , "Unknown device"); - } - - public void checkIfDeviceCanBeClosed() - { - if (juceOpenedPorts.size() == 0) - { - // never close bluetooth LE devices, otherwise they unpair and we have - // no idea how many ports they have. - // Only remove bluetooth devices when we specifically unpair - if (bluetoothAddress.equals ("")) - { - try - { - handle.close(); - handle = null; - } - catch (IOException e) - { - Log.d ("JUCE", "PhysicalMidiDevice::checkIfDeviceCanBeClosed: IOException = " + e.toString()); - } - } - } - } - - public void removePort (int portIdx, boolean isInput) - { - MidiPortID portID = new MidiPortID (portIdx, isInput); - JuceMidiPort port = juceOpenedPorts.get (portID); - - if (port != null) - { - juceOpenedPorts.remove (portID); - checkIfDeviceCanBeClosed(); - return; - } - - // tried to remove a port that was never added - assert false; - } - - public JuceMidiPort openPort (int portIdx, boolean isInput, long host) - { - open(); - - if (handle == null) - { - Log.d ("JUCE", "PhysicalMidiDevice::openPort: handle = null, device not open"); - return null; - } - - // make sure that the port is not already open - if (findPortForIdx (portIdx, isInput) != null) - { - Log.d ("JUCE", "PhysicalMidiDevice::openInputPort: port already open, not opening again!"); - return null; - } - - JuceMidiPort retval = null; - - if (isInput) - { - MidiOutputPort androidPort = handle.openOutputPort (portIdx); - - if (androidPort == null) - { - Log.d ("JUCE", "PhysicalMidiDevice::openPort: MidiDevice::openOutputPort (portIdx = " - + Integer.toString (portIdx) + ") failed!"); - return null; - } - - retval = new JuceMidiInputPort (this, host, androidPort); - } - else - { - MidiInputPort androidPort = handle.openInputPort (portIdx); - - if (androidPort == null) - { - Log.d ("JUCE", "PhysicalMidiDevice::openPort: MidiDevice::openInputPort (portIdx = " - + Integer.toString (portIdx) + ") failed!"); - return null; - } - - retval = new JuceMidiOutputPort (this, androidPort); - } - - juceOpenedPorts.put (new MidiPortID (portIdx, isInput), retval); - return retval; - } - - private JuceMidiPort findPortForIdx (int idx, boolean isInput) - { - return juceOpenedPorts.get (new MidiPortID (idx, isInput)); - } - - // opens the device - private synchronized void open() - { - if (handle != null) - return; - - Object waitForCreation = new Object(); - MidiDeviceThread thread = new MidiDeviceThread (waitForCreation); - thread.start(); - - synchronized(waitForCreation) - { - while (thread.handler == null) - { - try - { - waitForCreation.wait(); - } - catch (InterruptedException e) - { - Log.d ("JUCE", "wait was interrupted but we don't care"); - } - } - } - - Object waitForDevice = new Object(); - - MidiDeviceOpenCallback openCallback = new MidiDeviceOpenCallback (waitForDevice); - - synchronized (waitForDevice) - { - midiManager.openDevice (info, openCallback, thread.handler); - - while (openCallback.isWaiting) - { - try - { - waitForDevice.wait(); - } - catch (InterruptedException e) - { - Log.d ("JUCE", "wait was interrupted but we don't care"); - } - } - } - - handle = openCallback.theDevice; - } - - private MidiDeviceInfo info; - private Hashtable juceOpenedPorts; - public MidiDevice handle; - public String bluetoothAddress; - private MidiManager midiManager; - } - - //============================================================================== - public class MidiDeviceManager extends MidiManager.DeviceCallback - { - public class MidiPortPath - { - public PhysicalMidiDevice midiDevice; - public int androidMidiPortID; - public int portIndexToUseInName; - } - - public class JuceDeviceList - { - public ArrayList inPorts = new ArrayList(); - public ArrayList outPorts = new ArrayList(); - } - - // We need to keep a thread local copy of the devices - // which we returned the last time - // getJuceAndroidMidiIn/OutputDevices() was called - private final ThreadLocal lastDevicesReturned = - new ThreadLocal() - { - @Override protected JuceDeviceList initialValue() - { - return new JuceDeviceList(); - } - }; - - public MidiDeviceManager() - { - physicalMidiDevices = new ArrayList(); - manager = (MidiManager) getSystemService (MIDI_SERVICE); - - if (manager == null) - { - Log.d ("JUCE", "MidiDeviceManager error: could not get MidiManager system service"); - return; - } - - manager.registerDeviceCallback (this, null); - - MidiDeviceInfo[] foundDevices = manager.getDevices(); - - for (MidiDeviceInfo info : foundDevices) - physicalMidiDevices.add (PhysicalMidiDevice.fromMidiDeviceInfo (info, manager)); - } - - // specifically add a device to the list - public void addDeviceToList (PhysicalMidiDevice device) - { - physicalMidiDevices.add (device); - } - - public void unpairBluetoothDevice (String address) - { - for (int i = 0; i < physicalMidiDevices.size(); ++i) - { - PhysicalMidiDevice device = physicalMidiDevices.get(i); - - if (device.bluetoothAddress.equals (address)) - { - physicalMidiDevices.remove (i); - device.unpair(); - return; - } - } - } - - public boolean isBluetoothDevicePaired (String address) - { - for (int i = 0; i < physicalMidiDevices.size(); ++i) - { - PhysicalMidiDevice device = physicalMidiDevices.get(i); - - if (device.bluetoothAddress.equals (address)) - return true; - } - - return false; - } - - public String[] getJuceAndroidMidiInputDevices() - { - return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_INPUT); - } - - public String[] getJuceAndroidMidiOutputDevices() - { - return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_OUTPUT); - } - - private String[] getJuceAndroidMidiDevices (int portType) - { - ArrayList listOfReturnedDevices = new ArrayList(); - List deviceNames = new ArrayList(); - - for (PhysicalMidiDevice physicalMidiDevice : physicalMidiDevices) - { - int portIdx = 0; - MidiDeviceInfo.PortInfo[] ports = physicalMidiDevice.getPorts(); - - for (MidiDeviceInfo.PortInfo port : ports) - { - if (port.getType() == portType) - { - MidiPortPath path = new MidiPortPath(); - path.midiDevice = physicalMidiDevice; - path.androidMidiPortID = port.getPortNumber(); - path.portIndexToUseInName = ++portIdx; - listOfReturnedDevices.add (path); - - deviceNames.add (physicalMidiDevice.getHumanReadableNameForPort (port, - path.portIndexToUseInName)); - } - } - } - - String[] deviceNamesArray = new String[deviceNames.size()]; - - if (portType == MidiDeviceInfo.PortInfo.TYPE_INPUT) - { - lastDevicesReturned.get().inPorts.clear(); - lastDevicesReturned.get().inPorts.addAll (listOfReturnedDevices); - } - else - { - lastDevicesReturned.get().outPorts.clear(); - lastDevicesReturned.get().outPorts.addAll (listOfReturnedDevices); - } - - return deviceNames.toArray(deviceNamesArray); - } - - public JuceMidiPort openMidiInputPortWithJuceIndex (int index, long host) - { - ArrayList lastDevices = lastDevicesReturned.get().inPorts; - - if (index >= lastDevices.size() || index < 0) - return null; - - MidiPortPath path = lastDevices.get (index); - return path.midiDevice.openPort (path.androidMidiPortID, true, host); - } - - public JuceMidiPort openMidiOutputPortWithJuceIndex (int index) - { - ArrayList lastDevices = lastDevicesReturned.get().outPorts; - - if (index >= lastDevices.size() || index < 0) - return null; - - MidiPortPath path = lastDevices.get (index); - return path.midiDevice.openPort (path.androidMidiPortID, false, 0); - } - - public String getInputPortNameForJuceIndex (int index) - { - ArrayList lastDevices = lastDevicesReturned.get().inPorts; - - if (index >= lastDevices.size() || index < 0) - return ""; - - MidiPortPath path = lastDevices.get (index); - - return path.midiDevice.getHumanReadableNameForPort (MidiDeviceInfo.PortInfo.TYPE_INPUT, - path.androidMidiPortID, - path.portIndexToUseInName); - } - - public String getOutputPortNameForJuceIndex (int index) - { - ArrayList lastDevices = lastDevicesReturned.get().outPorts; - - if (index >= lastDevices.size() || index < 0) - return ""; - - MidiPortPath path = lastDevices.get (index); - - return path.midiDevice.getHumanReadableNameForPort (MidiDeviceInfo.PortInfo.TYPE_OUTPUT, - path.androidMidiPortID, - path.portIndexToUseInName); - } - - public void onDeviceAdded (MidiDeviceInfo info) - { - PhysicalMidiDevice device = PhysicalMidiDevice.fromMidiDeviceInfo (info, manager); - - // Do not add bluetooth devices as they are already added by the native bluetooth dialog - if (info.getType() != MidiDeviceInfo.TYPE_BLUETOOTH) - physicalMidiDevices.add (device); - } - - public void onDeviceRemoved (MidiDeviceInfo info) - { - for (int i = 0; i < physicalMidiDevices.size(); ++i) - { - if (physicalMidiDevices.get(i).info.getId() == info.getId()) - { - physicalMidiDevices.remove (i); - return; - } - } - // Don't assert here as this may be called again after a bluetooth device is unpaired - } - - public void onDeviceStatusChanged (MidiDeviceStatus status) - { - } - - private ArrayList physicalMidiDevices; - private MidiManager manager; - } - - public MidiDeviceManager getAndroidMidiDeviceManager() - { - if (getSystemService (MIDI_SERVICE) == null) - return null; - - synchronized (MidiTest.class) - { - if (midiDeviceManager == null) - midiDeviceManager = new MidiDeviceManager(); - } - - return midiDeviceManager; - } - - public BluetoothManager getAndroidBluetoothManager() - { - BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); - - if (adapter == null) - return null; - - if (adapter.getBluetoothLeScanner() == null) - return null; - - synchronized (MidiTest.class) - { - if (bluetoothManager == null) - bluetoothManager = new BluetoothManager(); - } - - return bluetoothManager; - } - - //============================================================================== - @Override - public void onCreate (Bundle savedInstanceState) - { - super.onCreate (savedInstanceState); - - isScreenSaverEnabled = true; - hideActionBar(); - viewHolder = new ViewHolder (this); - setContentView (viewHolder); - - setVolumeControlStream (AudioManager.STREAM_MUSIC); - } - - @Override - protected void onDestroy() - { - quitApp(); - super.onDestroy(); - - clearDataCache(); - } - - @Override - protected void onPause() - { - suspendApp(); - super.onPause(); - } - - @Override - protected void onResume() - { - super.onResume(); - resumeApp(); - } - - @Override - public void onConfigurationChanged (Configuration cfg) - { - super.onConfigurationChanged (cfg); - setContentView (viewHolder); - } - - private void callAppLauncher() - { - launchApp (getApplicationInfo().publicSourceDir, - getApplicationInfo().dataDir); - } - - private void hideActionBar() - { - // get "getActionBar" method - java.lang.reflect.Method getActionBarMethod = null; - try - { - getActionBarMethod = this.getClass().getMethod ("getActionBar"); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (getActionBarMethod == null) return; - - // invoke "getActionBar" method - Object actionBar = null; - try - { - actionBar = getActionBarMethod.invoke (this); - } - catch (java.lang.IllegalArgumentException e) { return; } - catch (java.lang.IllegalAccessException e) { return; } - catch (java.lang.reflect.InvocationTargetException e) { return; } - if (actionBar == null) return; - - // get "hide" method - java.lang.reflect.Method actionBarHideMethod = null; - try - { - actionBarHideMethod = actionBar.getClass().getMethod ("hide"); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (actionBarHideMethod == null) return; - - // invoke "hide" method - try - { - actionBarHideMethod.invoke (actionBar); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - } - - //============================================================================== - private native void launchApp (String appFile, String appDataDir); - private native void quitApp(); - private native void suspendApp(); - private native void resumeApp(); - private native void setScreenSize (int screenWidth, int screenHeight, int dpi); - - //============================================================================== - public native void deliverMessage (long value); - private android.os.Handler messageHandler = new android.os.Handler(); - - public final void postMessage (long value) - { - messageHandler.post (new MessageCallback (value)); - } - - private final class MessageCallback implements Runnable - { - public MessageCallback (long value_) { value = value_; } - public final void run() { deliverMessage (value); } - - private long value; - } - - //============================================================================== - private ViewHolder viewHolder; - private MidiDeviceManager midiDeviceManager = null; - private BluetoothManager bluetoothManager = null; - private boolean isScreenSaverEnabled; - private java.util.Timer keepAliveTimer; - - public final ComponentPeerView createNewView (boolean opaque, long host) - { - ComponentPeerView v = new ComponentPeerView (this, opaque, host); - viewHolder.addView (v); - return v; - } - - public final void deleteView (ComponentPeerView view) - { - ViewGroup group = (ViewGroup) (view.getParent()); - - if (group != null) - group.removeView (view); - } - - public final void deleteNativeSurfaceView (NativeSurfaceView view) - { - ViewGroup group = (ViewGroup) (view.getParent()); - - if (group != null) - group.removeView (view); - } - - final class ViewHolder extends ViewGroup - { - public ViewHolder (Context context) - { - super (context); - setDescendantFocusability (ViewGroup.FOCUS_AFTER_DESCENDANTS); - setFocusable (false); - } - - protected final void onLayout (boolean changed, int left, int top, int right, int bottom) - { - setScreenSize (getWidth(), getHeight(), getDPI()); - - if (isFirstResize) - { - isFirstResize = false; - callAppLauncher(); - } - } - - private final int getDPI() - { - DisplayMetrics metrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics (metrics); - return metrics.densityDpi; - } - - private boolean isFirstResize = true; - } - - public final void excludeClipRegion (android.graphics.Canvas canvas, float left, float top, float right, float bottom) - { - canvas.clipRect (left, top, right, bottom, android.graphics.Region.Op.DIFFERENCE); - } - - //============================================================================== - public final void setScreenSaver (boolean enabled) - { - if (isScreenSaverEnabled != enabled) - { - isScreenSaverEnabled = enabled; - - if (keepAliveTimer != null) - { - keepAliveTimer.cancel(); - keepAliveTimer = null; - } - - if (enabled) - { - getWindow().clearFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - else - { - getWindow().addFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - - // If no user input is received after about 3 seconds, the OS will lower the - // task's priority, so this timer forces it to be kept active. - keepAliveTimer = new java.util.Timer(); - - keepAliveTimer.scheduleAtFixedRate (new TimerTask() - { - @Override - public void run() - { - android.app.Instrumentation instrumentation = new android.app.Instrumentation(); - - try - { - instrumentation.sendKeyDownUpSync (KeyEvent.KEYCODE_UNKNOWN); - } - catch (Exception e) - { - } - } - }, 2000, 2000); - } - } - } - - public final boolean getScreenSaver() - { - return isScreenSaverEnabled; - } - - //============================================================================== - public final String getClipboardContent() - { - ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE); - return clipboard.getText().toString(); - } - - public final void setClipboardContent (String newText) - { - ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE); - clipboard.setText (newText); - } - - //============================================================================== - public final void showMessageBox (String title, String message, final long callback) - { - AlertDialog.Builder builder = new AlertDialog.Builder (this); - builder.setTitle (title) - .setMessage (message) - .setCancelable (true) - .setPositiveButton ("OK", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.cancel(); - MidiTest.this.alertDismissed (callback, 0); - } - }); - - builder.create().show(); - } - - public final void showOkCancelBox (String title, String message, final long callback) - { - AlertDialog.Builder builder = new AlertDialog.Builder (this); - builder.setTitle (title) - .setMessage (message) - .setCancelable (true) - .setPositiveButton ("OK", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.cancel(); - MidiTest.this.alertDismissed (callback, 1); - } - }) - .setNegativeButton ("Cancel", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.cancel(); - MidiTest.this.alertDismissed (callback, 0); - } - }); - - builder.create().show(); - } - - public final void showYesNoCancelBox (String title, String message, final long callback) - { - AlertDialog.Builder builder = new AlertDialog.Builder (this); - builder.setTitle (title) - .setMessage (message) - .setCancelable (true) - .setPositiveButton ("Yes", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.cancel(); - MidiTest.this.alertDismissed (callback, 1); - } - }) - .setNegativeButton ("No", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.cancel(); - MidiTest.this.alertDismissed (callback, 2); - } - }) - .setNeutralButton ("Cancel", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.cancel(); - MidiTest.this.alertDismissed (callback, 0); - } - }); - - builder.create().show(); - } - - public native void alertDismissed (long callback, int id); - - //============================================================================== - public final class ComponentPeerView extends ViewGroup - implements View.OnFocusChangeListener - { - public ComponentPeerView (Context context, boolean opaque_, long host) - { - super (context); - this.host = host; - setWillNotDraw (false); - opaque = opaque_; - - setFocusable (true); - setFocusableInTouchMode (true); - setOnFocusChangeListener (this); - requestFocus(); - - // swap red and blue colours to match internal opengl texture format - ColorMatrix colorMatrix = new ColorMatrix(); - - float[] colorTransform = { 0, 0, 1.0f, 0, 0, - 0, 1.0f, 0, 0, 0, - 1.0f, 0, 0, 0, 0, - 0, 0, 0, 1.0f, 0 }; - - colorMatrix.set (colorTransform); - paint.setColorFilter (new ColorMatrixColorFilter (colorMatrix)); - } - - //============================================================================== - private native void handlePaint (long host, Canvas canvas, Paint paint); - - @Override - public void onDraw (Canvas canvas) - { - handlePaint (host, canvas, paint); - } - - @Override - public boolean isOpaque() - { - return opaque; - } - - private boolean opaque; - private long host; - private Paint paint = new Paint(); - - //============================================================================== - private native void handleMouseDown (long host, int index, float x, float y, long time); - private native void handleMouseDrag (long host, int index, float x, float y, long time); - private native void handleMouseUp (long host, int index, float x, float y, long time); - - @Override - public boolean onTouchEvent (MotionEvent event) - { - int action = event.getAction(); - long time = event.getEventTime(); - - switch (action & MotionEvent.ACTION_MASK) - { - case MotionEvent.ACTION_DOWN: - handleMouseDown (host, event.getPointerId(0), event.getX(), event.getY(), time); - return true; - - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - handleMouseUp (host, event.getPointerId(0), event.getX(), event.getY(), time); - return true; - - case MotionEvent.ACTION_MOVE: - { - int n = event.getPointerCount(); - for (int i = 0; i < n; ++i) - handleMouseDrag (host, event.getPointerId(i), event.getX(i), event.getY(i), time); - - return true; - } - - case MotionEvent.ACTION_POINTER_UP: - { - int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - handleMouseUp (host, event.getPointerId(i), event.getX(i), event.getY(i), time); - return true; - } - - case MotionEvent.ACTION_POINTER_DOWN: - { - int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - handleMouseDown (host, event.getPointerId(i), event.getX(i), event.getY(i), time); - return true; - } - - default: - break; - } - - return false; - } - - //============================================================================== - private native void handleKeyDown (long host, int keycode, int textchar); - private native void handleKeyUp (long host, int keycode, int textchar); - - public void showKeyboard (String type) - { - InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); - - if (imm != null) - { - if (type.length() > 0) - { - imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); - imm.setInputMethod (getWindowToken(), type); - } - else - { - imm.hideSoftInputFromWindow (getWindowToken(), 0); - } - } - } - - @Override - public boolean onKeyDown (int keyCode, KeyEvent event) - { - switch (keyCode) - { - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: - return super.onKeyDown (keyCode, event); - - default: break; - } - - handleKeyDown (host, keyCode, event.getUnicodeChar()); - return true; - } - - @Override - public boolean onKeyUp (int keyCode, KeyEvent event) - { - handleKeyUp (host, keyCode, event.getUnicodeChar()); - return true; - } - - @Override - public boolean onKeyMultiple (int keyCode, int count, KeyEvent event) - { - if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction() != KeyEvent.ACTION_MULTIPLE) - return super.onKeyMultiple (keyCode, count, event); - - if (event.getCharacters() != null) - { - int utf8Char = event.getCharacters().codePointAt (0); - handleKeyDown (host, utf8Char, utf8Char); - return true; - } - - return false; - } - - // this is here to make keyboard entry work on a Galaxy Tab2 10.1 - @Override - public InputConnection onCreateInputConnection (EditorInfo outAttrs) - { - outAttrs.actionLabel = ""; - outAttrs.hintText = ""; - outAttrs.initialCapsMode = 0; - outAttrs.initialSelEnd = outAttrs.initialSelStart = -1; - outAttrs.label = ""; - outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI; - outAttrs.inputType = InputType.TYPE_NULL; - - return new BaseInputConnection (this, false); - } - - //============================================================================== - @Override - protected void onSizeChanged (int w, int h, int oldw, int oldh) - { - super.onSizeChanged (w, h, oldw, oldh); - viewSizeChanged (host); - } - - @Override - protected void onLayout (boolean changed, int left, int top, int right, int bottom) - { - for (int i = getChildCount(); --i >= 0;) - requestTransparentRegion (getChildAt (i)); - } - - private native void viewSizeChanged (long host); - - @Override - public void onFocusChange (View v, boolean hasFocus) - { - if (v == this) - focusChanged (host, hasFocus); - } - - private native void focusChanged (long host, boolean hasFocus); - - public void setViewName (String newName) {} - - public boolean isVisible() { return getVisibility() == VISIBLE; } - public void setVisible (boolean b) { setVisibility (b ? VISIBLE : INVISIBLE); } - - public boolean containsPoint (int x, int y) - { - return true; //xxx needs to check overlapping views - } - } - - //============================================================================== - public static class NativeSurfaceView extends SurfaceView - implements SurfaceHolder.Callback - { - private long nativeContext = 0; - - NativeSurfaceView (Context context, long nativeContextPtr) - { - super (context); - nativeContext = nativeContextPtr; - } - - public Surface getNativeSurface() - { - Surface retval = null; - - SurfaceHolder holder = getHolder(); - if (holder != null) - retval = holder.getSurface(); - - return retval; - } - - //============================================================================== - @Override - public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) - { - surfaceChangedNative (nativeContext, holder, format, width, height); - } - - @Override - public void surfaceCreated (SurfaceHolder holder) - { - surfaceCreatedNative (nativeContext, holder); - } - - @Override - public void surfaceDestroyed (SurfaceHolder holder) - { - surfaceDestroyedNative (nativeContext, holder); - } - - @Override - protected void dispatchDraw (Canvas canvas) - { - super.dispatchDraw (canvas); - dispatchDrawNative (nativeContext, canvas); - } - - //============================================================================== - @Override - protected void onAttachedToWindow () - { - super.onAttachedToWindow(); - getHolder().addCallback (this); - } - - @Override - protected void onDetachedFromWindow () - { - super.onDetachedFromWindow(); - getHolder().removeCallback (this); - } - - //============================================================================== - private native void dispatchDrawNative (long nativeContextPtr, Canvas canvas); - private native void surfaceCreatedNative (long nativeContextptr, SurfaceHolder holder); - private native void surfaceDestroyedNative (long nativeContextptr, SurfaceHolder holder); - private native void surfaceChangedNative (long nativeContextptr, SurfaceHolder holder, - int format, int width, int height); - } - - public NativeSurfaceView createNativeSurfaceView (long nativeSurfacePtr) - { - return new NativeSurfaceView (this, nativeSurfacePtr); - } - - //============================================================================== - public final int[] renderGlyph (char glyph, Paint paint, android.graphics.Matrix matrix, Rect bounds) - { - Path p = new Path(); - paint.getTextPath (String.valueOf (glyph), 0, 1, 0.0f, 0.0f, p); - - RectF boundsF = new RectF(); - p.computeBounds (boundsF, true); - matrix.mapRect (boundsF); - - boundsF.roundOut (bounds); - bounds.left--; - bounds.right++; - - final int w = bounds.width(); - final int h = Math.max (1, bounds.height()); - - Bitmap bm = Bitmap.createBitmap (w, h, Bitmap.Config.ARGB_8888); - - Canvas c = new Canvas (bm); - matrix.postTranslate (-bounds.left, -bounds.top); - c.setMatrix (matrix); - c.drawPath (p, paint); - - final int sizeNeeded = w * h; - if (cachedRenderArray.length < sizeNeeded) - cachedRenderArray = new int [sizeNeeded]; - - bm.getPixels (cachedRenderArray, 0, w, 0, 0, w, h); - bm.recycle(); - return cachedRenderArray; - } - - private int[] cachedRenderArray = new int [256]; - - //============================================================================== - public static class HTTPStream - { - public HTTPStream (HttpURLConnection connection_, - int[] statusCode, StringBuffer responseHeaders) throws IOException - { - connection = connection_; - - try - { - inputStream = new BufferedInputStream (connection.getInputStream()); - } - catch (IOException e) - { - if (connection.getResponseCode() < 400) - throw e; - } - finally - { - statusCode[0] = connection.getResponseCode(); - } - - if (statusCode[0] >= 400) - inputStream = connection.getErrorStream(); - else - inputStream = connection.getInputStream(); - - for (java.util.Map.Entry> entry : connection.getHeaderFields().entrySet()) - if (entry.getKey() != null && entry.getValue() != null) - responseHeaders.append (entry.getKey() + ": " - + android.text.TextUtils.join (",", entry.getValue()) + "\n"); - } - - public final void release() - { - try - { - inputStream.close(); - } - catch (IOException e) - {} - - connection.disconnect(); - } - - public final int read (byte[] buffer, int numBytes) - { - int num = 0; - - try - { - num = inputStream.read (buffer, 0, numBytes); - } - catch (IOException e) - {} - - if (num > 0) - position += num; - - return num; - } - - public final long getPosition() { return position; } - public final long getTotalLength() { return -1; } - public final boolean isExhausted() { return false; } - public final boolean setPosition (long newPos) { return false; } - - private HttpURLConnection connection; - private InputStream inputStream; - private long position; - } - - public static final HTTPStream createHTTPStream (String address, boolean isPost, byte[] postData, - String headers, int timeOutMs, int[] statusCode, - StringBuffer responseHeaders, int numRedirectsToFollow, - String httpRequestCmd) - { - // timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL) - if (timeOutMs < 0) - timeOutMs = 0; - else if (timeOutMs == 0) - timeOutMs = 30000; - - // headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines. - // So convert headers string to an array, with an element for each line - String headerLines[] = headers.split("\\n"); - - for (;;) - { - try - { - HttpURLConnection connection = (HttpURLConnection) (new URL(address).openConnection()); - - if (connection != null) - { - try - { - connection.setInstanceFollowRedirects (false); - connection.setConnectTimeout (timeOutMs); - connection.setReadTimeout (timeOutMs); - - // Set request headers - for (int i = 0; i < headerLines.length; ++i) - { - int pos = headerLines[i].indexOf (":"); - - if (pos > 0 && pos < headerLines[i].length()) - { - String field = headerLines[i].substring (0, pos); - String value = headerLines[i].substring (pos + 1); - - if (value.length() > 0) - connection.setRequestProperty (field, value); - } - } - - connection.setRequestMethod (httpRequestCmd); - if (isPost) - { - connection.setDoOutput (true); - - if (postData != null) - { - OutputStream out = connection.getOutputStream(); - out.write(postData); - out.flush(); - } - } - - HTTPStream httpStream = new HTTPStream (connection, statusCode, responseHeaders); - - // Process redirect & continue as necessary - int status = statusCode[0]; - - if (--numRedirectsToFollow >= 0 - && (status == 301 || status == 302 || status == 303 || status == 307)) - { - // Assumes only one occurrence of "Location" - int pos1 = responseHeaders.indexOf ("Location:") + 10; - int pos2 = responseHeaders.indexOf ("\n", pos1); - - if (pos2 > pos1) - { - String newLocation = responseHeaders.substring(pos1, pos2); - // Handle newLocation whether it's absolute or relative - URL baseUrl = new URL (address); - URL newUrl = new URL (baseUrl, newLocation); - String transformedNewLocation = newUrl.toString(); - - if (transformedNewLocation != address) - { - address = transformedNewLocation; - // Clear responseHeaders before next iteration - responseHeaders.delete (0, responseHeaders.length()); - continue; - } - } - } - - return httpStream; - } - catch (Throwable e) - { - connection.disconnect(); - } - } - } - catch (Throwable e) {} - - return null; - } - } - - public final void launchURL (String url) - { - startActivity (new Intent (Intent.ACTION_VIEW, Uri.parse (url))); - } - - public static final String getLocaleValue (boolean isRegion) - { - java.util.Locale locale = java.util.Locale.getDefault(); - - return isRegion ? locale.getDisplayCountry (java.util.Locale.US) - : locale.getDisplayLanguage (java.util.Locale.US); - } - - private static final String getFileLocation (String type) - { - return Environment.getExternalStoragePublicDirectory (type).getAbsolutePath(); - } - - public static final String getDocumentsFolder() { return Environment.getDataDirectory().getAbsolutePath(); } - public static final String getPicturesFolder() { return getFileLocation (Environment.DIRECTORY_PICTURES); } - public static final String getMusicFolder() { return getFileLocation (Environment.DIRECTORY_MUSIC); } - public static final String getMoviesFolder() { return getFileLocation (Environment.DIRECTORY_MOVIES); } - public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); } - - //============================================================================== - private final class SingleMediaScanner implements MediaScannerConnectionClient - { - public SingleMediaScanner (Context context, String filename) - { - file = filename; - msc = new MediaScannerConnection (context, this); - msc.connect(); - } - - @Override - public void onMediaScannerConnected() - { - msc.scanFile (file, null); - } - - @Override - public void onScanCompleted (String path, Uri uri) - { - msc.disconnect(); - } - - private MediaScannerConnection msc; - private String file; - } - - public final void scanFile (String filename) - { - new SingleMediaScanner (this, filename); - } - - public final Typeface getTypeFaceFromAsset (String assetName) - { - try - { - return Typeface.createFromAsset (this.getResources().getAssets(), assetName); - } - catch (Throwable e) {} - - return null; - } - - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); - - public static String bytesToHex (byte[] bytes) - { - char[] hexChars = new char[bytes.length * 2]; - - for (int j = 0; j < bytes.length; ++j) - { - int v = bytes[j] & 0xff; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0f]; - } - - return new String (hexChars); - } - - final private java.util.Map dataCache = new java.util.HashMap(); - - synchronized private final File getDataCacheFile (byte[] data) - { - try - { - java.security.MessageDigest digest = java.security.MessageDigest.getInstance ("MD5"); - digest.update (data); - - String key = bytesToHex (digest.digest()); - - if (dataCache.containsKey (key)) - return (File) dataCache.get (key); - - File f = new File (this.getCacheDir(), "bindata_" + key); - f.delete(); - FileOutputStream os = new FileOutputStream (f); - os.write (data, 0, data.length); - dataCache.put (key, f); - return f; - } - catch (Throwable e) {} - - return null; - } - - private final void clearDataCache() - { - java.util.Iterator it = dataCache.values().iterator(); - - while (it.hasNext()) - { - File f = (File) it.next(); - f.delete(); - } - } - - public final Typeface getTypeFaceFromByteArray (byte[] data) - { - try - { - File f = getDataCacheFile (data); - - if (f != null) - return Typeface.createFromFile (f); - } - catch (Exception e) - { - Log.e ("JUCE", e.toString()); - } - - return null; - } - - public final int getAndroidSDKVersion() - { - return android.os.Build.VERSION.SDK_INT; - } - - public final String audioManagerGetProperty (String property) - { - Object obj = getSystemService (AUDIO_SERVICE); - if (obj == null) - return null; - - java.lang.reflect.Method method; - - try - { - method = obj.getClass().getMethod ("getProperty", String.class); - } - catch (SecurityException e) { return null; } - catch (NoSuchMethodException e) { return null; } - - if (method == null) - return null; - - try - { - return (String) method.invoke (obj, property); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - - return null; - } - - public final int setCurrentThreadPriority (int priority) - { - android.os.Process.setThreadPriority (android.os.Process.myTid(), priority); - return android.os.Process.getThreadPriority (android.os.Process.myTid()); - } - - public final boolean hasSystemFeature (String property) - { - return getPackageManager().hasSystemFeature (property); - } - - private static class JuceThread extends Thread - { - public JuceThread (long host, String threadName, long threadStackSize) - { - super (null, null, threadName, threadStackSize); - _this = host; - } - - public void run() - { - runThread(_this); - } - - private native void runThread (long host); - private long _this; - } - - public final Thread createNewThread(long host, String threadName, long threadStackSize) - { - return new JuceThread(host, threadName, threadStackSize); - } -} diff --git a/examples/MidiTest/Builds/MacOSX/MidiTest.xcodeproj/project.pbxproj b/examples/MidiTest/Builds/MacOSX/MidiTest.xcodeproj/project.pbxproj index 440947c49d..bcb2cff771 100644 --- a/examples/MidiTest/Builds/MacOSX/MidiTest.xcodeproj/project.pbxproj +++ b/examples/MidiTest/Builds/MacOSX/MidiTest.xcodeproj/project.pbxproj @@ -497,18 +497,18 @@ 85CEAF5ACCB37816C3B4E164 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GraphicsContext.cpp"; path = "../../../../modules/juce_graphics/contexts/juce_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; 85D5A35174B569C59CF2C7F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; }; 86771CD55EEBF4DCD6B3EE1C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ProgressBar.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.cpp"; sourceTree = "SOURCE_ROOT"; }; - 86ADBCA3CFDA607F9E22805E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Timer.cpp"; path = "../../../../modules/juce_events/timers/juce_Timer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 869267FDBCC5DA2192C28D1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DeletedAtShutdown.cpp"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.cpp"; sourceTree = "SOURCE_ROOT"; }; 86FA92C698D7FA9BB526A62F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadWithProgressWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h"; sourceTree = "SOURCE_ROOT"; }; 8742F468DF1905F097D7F6C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioThumbnail.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioThumbnail.h"; sourceTree = "SOURCE_ROOT"; }; 875A14BB773AFC27135869A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; 8781C749016774125396B268 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VSTPluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 87E96BA5A9FFCA433E0453C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RuntimePermissions.h"; path = "../../../../modules/juce_core/misc/juce_RuntimePermissions.h"; sourceTree = "SOURCE_ROOT"; }; 87EA6E46F50CE9F1225F5378 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; 88B3C4FF9311F4797F9BDCCA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; 89377CF5085E5D9000164FE6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RecentlyOpenedFilesList.h"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"; sourceTree = "SOURCE_ROOT"; }; 896AAD6D2DE82AF4A1D9879D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MPENote.h"; path = "../../../../modules/juce_audio_basics/mpe/juce_MPENote.h"; sourceTree = "SOURCE_ROOT"; }; 896ACC6656C17EC51D99E5ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathIterator.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; 8989E5160769A8051DE396E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResamplingAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8A282A87C13A4CB559B544D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ActionBroadcaster.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; 8A4BBECEECC80FDC7DEA48B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBuilder.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.h"; sourceTree = "SOURCE_ROOT"; }; 8A9C5EBA0F19F7979A38DDF0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinate.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp"; sourceTree = "SOURCE_ROOT"; }; 8B336888A6EB8C1061C30F70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableObjectResizer.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h"; sourceTree = "SOURCE_ROOT"; }; @@ -526,6 +526,7 @@ 8E317934922B12ABA2B5A8AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeBroadcaster.h"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; 8E9358560B0ACE8A912B8AB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CoreAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; 8EE2944D2A3080C7D83EB741 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableCornerComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8EF7ED003297DFA5026CC445 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RuntimePermissions.cpp"; path = "../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"; sourceTree = "SOURCE_ROOT"; }; 8F56F2FA5C0D47F9EA19E09C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainComponent.cpp; path = ../../Source/MainComponent.cpp; sourceTree = "SOURCE_ROOT"; }; 8FF8814C6B322D670346712C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_basics.h"; path = "../../../../modules/juce_gui_basics/juce_gui_basics.h"; sourceTree = "SOURCE_ROOT"; }; 90794FCA3ACFCE9FF934CFCA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; @@ -536,8 +537,8 @@ 916C34DC7037A6ECB6B02ADC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WildcardFileFilter.cpp"; path = "../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; 91FA7F73B33D66D9C3A6FD9F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainComponent.h; path = ../../Source/MainComponent.h; sourceTree = "SOURCE_ROOT"; }; 92123D5456E4E881FDE03CF3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 924AD69D9805BF69CF891A26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectangleList.h"; path = "../../../../modules/juce_graphics/geometry/juce_RectangleList.h"; sourceTree = "SOURCE_ROOT"; }; 926BB03B7062274CF6152259 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPress.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.h"; sourceTree = "SOURCE_ROOT"; }; - 92E3ED2752ED738806E731C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; 9364B320302B675300E93B41 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IPAddress.h"; path = "../../../../modules/juce_core/network/juce_IPAddress.h"; sourceTree = "SOURCE_ROOT"; }; 938A89D7873B62E2FF8929B2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FlacAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; 9481495E00E43EBBCF41D165 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImagePreviewComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -549,7 +550,6 @@ 96136E8FAEE6D138EABDC874 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; }; 961694E31BDCEBFC65CC1796 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableHeaderComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; 963D38EE3DC00AE35DF2F33A = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; }; - 96C10BDED107AED6A992F38C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NotificationType.h"; path = "../../../../modules/juce_events/messages/juce_NotificationType.h"; sourceTree = "SOURCE_ROOT"; }; 97067DD5073A37AD706DDE95 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CarbonViewWrapperComponent.h"; path = "../../../../modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h"; sourceTree = "SOURCE_ROOT"; }; 97A2720B7633C85F8FDA6837 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MPEZone.cpp"; path = "../../../../modules/juce_audio_basics/mpe/juce_MPEZone.cpp"; sourceTree = "SOURCE_ROOT"; }; 97BD8C01E13C93693AD70692 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioThumbnail.cpp"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -558,28 +558,28 @@ 992E198BAFF9F97CA8267243 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; 99665EBB1C635EC8B198D415 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorEditor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; 9987B55A7D7AE452D921F227 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatWriter.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"; sourceTree = "SOURCE_ROOT"; }; - 99F3BE02BEA734C0197C607C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_MessageQueue.h"; path = "../../../../modules/juce_events/native/juce_osx_MessageQueue.h"; sourceTree = "SOURCE_ROOT"; }; 9A1630514C56BFA5361E93D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyListener.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"; sourceTree = "SOURCE_ROOT"; }; 9A458C31170E38D728FDC648 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ScrollBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ScrollBar.cpp"; sourceTree = "SOURCE_ROOT"; }; 9AC7FDA570544046185D6933 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChildProcess.h"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; 9AE96EFA03DB4690EC7D7EF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Viewport.h"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.h"; sourceTree = "SOURCE_ROOT"; }; 9B6CED77127E63CD68BFD16C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiFile.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiFile.h"; sourceTree = "SOURCE_ROOT"; }; 9BAED86761B8DDB97637DCB0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../../../modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; }; + 9BC778712D665C9DF94C08A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectanglePlacement.h"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.h"; sourceTree = "SOURCE_ROOT"; }; 9C25ACE300678F8DF5EEFCFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorGraph.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9CE0F9D7C49B64C29A699E3D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HyperlinkButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp"; sourceTree = "SOURCE_ROOT"; }; A0B754CEB65C70F3F3BF3352 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioThumbnailCache.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailCache.h"; sourceTree = "SOURCE_ROOT"; }; - A26FAD7AB054AE6BFC9F106E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FillType.cpp"; path = "../../../../modules/juce_graphics/colour/juce_FillType.cpp"; sourceTree = "SOURCE_ROOT"; }; - A49E4ACB0716C74EDC25DC50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_win32_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; A4AF80059F74FF502CAB1655 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSourcePlayer.h"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h"; sourceTree = "SOURCE_ROOT"; }; A70C237020E785056E276FD9 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 13966A9213FDBB55FF26B12F = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MidiTest.app; sourceTree = "BUILT_PRODUCTS_DIR"; }; - 869267FDBCC5DA2192C28D1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DeletedAtShutdown.cpp"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.cpp"; sourceTree = "SOURCE_ROOT"; }; - 924AD69D9805BF69CF891A26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectangleList.h"; path = "../../../../modules/juce_graphics/geometry/juce_RectangleList.h"; sourceTree = "SOURCE_ROOT"; }; + 86ADBCA3CFDA607F9E22805E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Timer.cpp"; path = "../../../../modules/juce_events/timers/juce_Timer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8A282A87C13A4CB559B544D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ActionBroadcaster.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; + 92E3ED2752ED738806E731C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + 96C10BDED107AED6A992F38C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NotificationType.h"; path = "../../../../modules/juce_events/messages/juce_NotificationType.h"; sourceTree = "SOURCE_ROOT"; }; 977004696868887798BE902E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationBase.cpp"; path = "../../../../modules/juce_events/messages/juce_ApplicationBase.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9BC778712D665C9DF94C08A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectanglePlacement.h"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.h"; sourceTree = "SOURCE_ROOT"; }; + 99F3BE02BEA734C0197C607C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_MessageQueue.h"; path = "../../../../modules/juce_events/native/juce_osx_MessageQueue.h"; sourceTree = "SOURCE_ROOT"; }; 9C00A3B72C9748ACFBF5C059 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferedInputStream.h"; path = "../../../../modules/juce_core/streams/juce_BufferedInputStream.h"; sourceTree = "SOURCE_ROOT"; }; 9C3D731E59E142B877B3B40A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Viewport.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.cpp"; sourceTree = "SOURCE_ROOT"; }; 9CDD6AA35716672F050A28C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoManager.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoManager.h"; sourceTree = "SOURCE_ROOT"; }; - 9CE0F9D7C49B64C29A699E3D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HyperlinkButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp"; sourceTree = "SOURCE_ROOT"; }; 9D113DD2FB3121F8AB55F1F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../../../modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; 9D8AA3AA516550BD848893D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MPESynthesiserVoice.h"; path = "../../../../modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h"; sourceTree = "SOURCE_ROOT"; }; 9DA13E7352FB376508315D83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputSource.h"; path = "../../../../modules/juce_core/streams/juce_FileInputSource.h"; sourceTree = "SOURCE_ROOT"; }; @@ -599,6 +599,7 @@ A1EAEF985828A65A8BB822E9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ElementComparator.h"; path = "../../../../modules/juce_core/containers/juce_ElementComparator.h"; sourceTree = "SOURCE_ROOT"; }; A2181237574C8E3CEC3D3C24 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableBorderComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h"; sourceTree = "SOURCE_ROOT"; }; A21D4A32B970D081ECF552F4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; }; + A26FAD7AB054AE6BFC9F106E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FillType.cpp"; path = "../../../../modules/juce_graphics/colour/juce_FillType.cpp"; sourceTree = "SOURCE_ROOT"; }; A2D5629F1BF85B126284E956 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CustomTypeface.h"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.h"; sourceTree = "SOURCE_ROOT"; }; A33F0C48ADF554C6A1DE55BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsContext.h"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; A356604B55EA59630DE40653 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -608,6 +609,7 @@ A3FB5EEBBC9502221F4B29EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CoreAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; A432857134F72B38C14CF6E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrayAllocationBase.h"; path = "../../../../modules/juce_core/containers/juce_ArrayAllocationBase.h"; sourceTree = "SOURCE_ROOT"; }; A45A580C2D7686A5A84F31F0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; + A49E4ACB0716C74EDC25DC50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_win32_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; A4A123FEBDE48FDDBEB74AED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Array.h"; path = "../../../../modules/juce_core/containers/juce_Array.h"; sourceTree = "SOURCE_ROOT"; }; A4BF427B5DC0D39311835749 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Network.cpp"; path = "../../../../modules/juce_core/native/juce_android_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; A4C85C1FBBAEF5CD869B481A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DragAndDropContainer.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -847,6 +849,7 @@ E73B23B093FDDF66346BFA5B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; E77E3C682E425FFB37A34DF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Variant.cpp"; path = "../../../../modules/juce_core/containers/juce_Variant.cpp"; sourceTree = "SOURCE_ROOT"; }; E7AC5DB63FE9C67DA227E2D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; }; + E8344472027EED5C371F79D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_RuntimePermissions.cpp"; path = "../../../../modules/juce_core/native/juce_android_RuntimePermissions.cpp"; sourceTree = "SOURCE_ROOT"; }; E8591ABA5B7B62C30D83359C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; E8796FBD2A6A0D79ADE450FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_linux_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; E87F503108182FD43982C45D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1357,6 +1360,8 @@ E6989A7A06F752F666765CD3 = {isa = PBXGroup; children = ( A1462538DDB60A384CA330C6, 33FC576912A6019A3F14604B, + 8EF7ED003297DFA5026CC445, + 87E96BA5A9FFCA433E0453C0, 94C3AA9784869B88B76D1F24, 79C23DAB6FB460C2A29A7815, B072058D4853C3D58657D667, ); name = misc; sourceTree = ""; }; @@ -1365,6 +1370,7 @@ DAC04A108BE4FB935F5A7D37, 0AFDB7BA03791E1D80ADD26A, A4BF427B5DC0D39311835749, + E8344472027EED5C371F79D9, 1A9227C1FF193983C98CB889, B77EFBE3AC6C32DBE89551B8, 522A524115FB924F7DE4A1CA, diff --git a/examples/MidiTest/Builds/VisualStudio2015/MidiTest.vcxproj b/examples/MidiTest/Builds/VisualStudio2015/MidiTest.vcxproj index 1ae9b9c25f..fd9a38551e 100644 --- a/examples/MidiTest/Builds/VisualStudio2015/MidiTest.vcxproj +++ b/examples/MidiTest/Builds/VisualStudio2015/MidiTest.vcxproj @@ -593,6 +593,9 @@ true + + true + true @@ -605,6 +608,9 @@ true + + true + true @@ -1466,6 +1472,7 @@ + diff --git a/examples/MidiTest/Builds/VisualStudio2015/MidiTest.vcxproj.filters b/examples/MidiTest/Builds/VisualStudio2015/MidiTest.vcxproj.filters index c02b0e7e08..ba2c293258 100644 --- a/examples/MidiTest/Builds/VisualStudio2015/MidiTest.vcxproj.filters +++ b/examples/MidiTest/Builds/VisualStudio2015/MidiTest.vcxproj.filters @@ -766,6 +766,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc @@ -778,6 +781,9 @@ Juce Modules\juce_core\native + + Juce Modules\juce_core\native + Juce Modules\juce_core\native @@ -2151,6 +2157,9 @@ Juce Modules\juce_core\misc + + Juce Modules\juce_core\misc + Juce Modules\juce_core\misc diff --git a/examples/MidiTest/Builds/iOS/MidiTest.xcodeproj/project.pbxproj b/examples/MidiTest/Builds/iOS/MidiTest.xcodeproj/project.pbxproj index 6801447267..307346bbe7 100644 --- a/examples/MidiTest/Builds/iOS/MidiTest.xcodeproj/project.pbxproj +++ b/examples/MidiTest/Builds/iOS/MidiTest.xcodeproj/project.pbxproj @@ -502,6 +502,7 @@ 8742F468DF1905F097D7F6C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioThumbnail.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioThumbnail.h"; sourceTree = "SOURCE_ROOT"; }; 875A14BB773AFC27135869A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; 8781C749016774125396B268 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VSTPluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 87E96BA5A9FFCA433E0453C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RuntimePermissions.h"; path = "../../../../modules/juce_core/misc/juce_RuntimePermissions.h"; sourceTree = "SOURCE_ROOT"; }; 87EA6E46F50CE9F1225F5378 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; 88B3C4FF9311F4797F9BDCCA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; 89377CF5085E5D9000164FE6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RecentlyOpenedFilesList.h"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"; sourceTree = "SOURCE_ROOT"; }; @@ -526,6 +527,7 @@ 8E317934922B12ABA2B5A8AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeBroadcaster.h"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; 8E9358560B0ACE8A912B8AB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CoreAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; 8EE2944D2A3080C7D83EB741 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableCornerComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8EF7ED003297DFA5026CC445 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RuntimePermissions.cpp"; path = "../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"; sourceTree = "SOURCE_ROOT"; }; 8F56F2FA5C0D47F9EA19E09C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainComponent.cpp; path = ../../Source/MainComponent.cpp; sourceTree = "SOURCE_ROOT"; }; 8FF8814C6B322D670346712C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_basics.h"; path = "../../../../modules/juce_gui_basics/juce_gui_basics.h"; sourceTree = "SOURCE_ROOT"; }; 90794FCA3ACFCE9FF934CFCA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; @@ -821,6 +823,7 @@ DD813DFB4467E734B53BD1F4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ValueTree.cpp"; path = "../../../../modules/juce_data_structures/values/juce_ValueTree.cpp"; sourceTree = "SOURCE_ROOT"; }; DE604B27DA8E8141012B7C76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SubregionStream.h"; path = "../../../../modules/juce_core/streams/juce_SubregionStream.h"; sourceTree = "SOURCE_ROOT"; }; DE62CAD14A6EA0B6F66E2B9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandTarget.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp"; sourceTree = "SOURCE_ROOT"; }; + DEED8BDABC10E6650C61915D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoableAction.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; DF1900E8201A1BCCBC64AF00 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DialogWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_DialogWindow.h"; sourceTree = "SOURCE_ROOT"; }; DF329E2274A09998C98424BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ValueTree.h"; path = "../../../../modules/juce_data_structures/values/juce_ValueTree.h"; sourceTree = "SOURCE_ROOT"; }; DF3DBAEDD9DEAEB7A7D0C246 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WaitableEvent.h"; path = "../../../../modules/juce_core/threads/juce_WaitableEvent.h"; sourceTree = "SOURCE_ROOT"; }; @@ -830,6 +833,7 @@ E04EBB578FEA27D7F991CD8A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedReadLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedReadLock.h"; sourceTree = "SOURCE_ROOT"; }; E112F8849FCF66DD34FD61A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Synthesiser.h"; path = "../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h"; sourceTree = "SOURCE_ROOT"; }; E13F0F8F7F6F633D94F8852E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageFileFormat.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageFileFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + E1A284EB48EF935B5BC692F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathIterator.h"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.h"; sourceTree = "SOURCE_ROOT"; }; E24CCE4B7AE25CA7990C9DCA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormat.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; E3259021F38C76FE5409C14C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDeviceSelectorComponent.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h"; sourceTree = "SOURCE_ROOT"; }; E37124530592B42579281C17 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConcertinaPanel.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.h"; sourceTree = "SOURCE_ROOT"; }; @@ -848,11 +852,10 @@ 13966A9213FDBB55FF26B12F = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MidiTest.app; sourceTree = "BUILT_PRODUCTS_DIR"; }; DEB45A52F4AAB4FF1DEFF917 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryOutputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; DEEBA624C3A1C4317AC9AE65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Message.h"; path = "../../../../modules/juce_events/messages/juce_Message.h"; sourceTree = "SOURCE_ROOT"; }; - DEED8BDABC10E6650C61915D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoableAction.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; - E1A284EB48EF935B5BC692F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathIterator.h"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.h"; sourceTree = "SOURCE_ROOT"; }; E4F40BEE2B9AD2278B514971 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UnitTest.h"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.h"; sourceTree = "SOURCE_ROOT"; }; E73B23B093FDDF66346BFA5B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; E7AC5DB63FE9C67DA227E2D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; }; + E8344472027EED5C371F79D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_RuntimePermissions.cpp"; path = "../../../../modules/juce_core/native/juce_android_RuntimePermissions.cpp"; sourceTree = "SOURCE_ROOT"; }; E8796FBD2A6A0D79ADE450FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_linux_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; E87F503108182FD43982C45D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; EA4E07555263482179C7F6B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioThumbnailCache.cpp"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1359,6 +1362,8 @@ E6989A7A06F752F666765CD3 = {isa = PBXGroup; children = ( A1462538DDB60A384CA330C6, 33FC576912A6019A3F14604B, + 8EF7ED003297DFA5026CC445, + 87E96BA5A9FFCA433E0453C0, 94C3AA9784869B88B76D1F24, 79C23DAB6FB460C2A29A7815, B072058D4853C3D58657D667, ); name = misc; sourceTree = ""; }; @@ -1367,6 +1372,7 @@ DAC04A108BE4FB935F5A7D37, 0AFDB7BA03791E1D80ADD26A, A4BF427B5DC0D39311835749, + E8344472027EED5C371F79D9, 1A9227C1FF193983C98CB889, B77EFBE3AC6C32DBE89551B8, 522A524115FB924F7DE4A1CA, diff --git a/examples/MidiTest/MidiTest.jucer b/examples/MidiTest/MidiTest.jucer index 01a3b3a280..bce1e12867 100644 --- a/examples/MidiTest/MidiTest.jucer +++ b/examples/MidiTest/MidiTest.jucer @@ -99,32 +99,32 @@ - + - - + + - - + + + - - - - - + + + + - + diff --git a/examples/MidiTest/Source/MainComponent.cpp b/examples/MidiTest/Source/MainComponent.cpp index e4ac1074d8..4ee22273a2 100755 --- a/examples/MidiTest/Source/MainComponent.cpp +++ b/examples/MidiTest/Source/MainComponent.cpp @@ -251,7 +251,9 @@ void MainContentComponent::resized() void MainContentComponent::buttonClicked (Button* buttonThatWasClicked) { if (buttonThatWasClicked == &pairButton) - BluetoothMidiDevicePairingDialogue::open(); + RuntimePermissions::request ( + RuntimePermissions::bluetoothMidi, + [] (bool wasGranted) { if (wasGranted) BluetoothMidiDevicePairingDialogue::open(); } ); } //==============================================================================