mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
Projucer: Add manifest option to allow virtual MIDI on Android
This commit is contained in:
parent
1c651e962b
commit
57ff869db0
2 changed files with 104 additions and 2 deletions
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class AndroidProjectExporter final : public ProjectExporter
|
||||
{
|
||||
|
|
@ -113,7 +112,8 @@ public:
|
|||
androidReadMediaVideoPermission, androidExternalWritePermission,
|
||||
androidInAppBillingPermission, androidVibratePermission, androidOtherPermissions, androidPushNotifications,
|
||||
androidEnableRemoteNotifications, androidRemoteNotificationsConfigFile, androidEnableContentSharing, androidKeyStore,
|
||||
androidKeyStorePass, androidKeyAlias, androidKeyAliasPass, gradleVersion, gradleToolchain, gradleClangTidy, androidPluginVersion;
|
||||
androidKeyStorePass, androidKeyAlias, androidKeyAliasPass, gradleVersion, gradleToolchain, gradleClangTidy, androidPluginVersion,
|
||||
androidEnableVirtualMidi;
|
||||
|
||||
//==============================================================================
|
||||
AndroidProjectExporter (Project& p, const ValueTree& t)
|
||||
|
|
@ -161,6 +161,7 @@ public:
|
|||
gradleToolchain (settings, Ids::gradleToolchain, getUndoManager(), "clang"),
|
||||
gradleClangTidy (settings, Ids::gradleClangTidy, getUndoManager(), false),
|
||||
androidPluginVersion (settings, Ids::androidPluginVersion, getUndoManager(), "8.10.0"),
|
||||
androidEnableVirtualMidi (settings, Ids::androidEnableVirtualMidi, getUndoManager(), false),
|
||||
AndroidExecutable (getAppSettings().getStoredPath (Ids::androidStudioExePath, TargetOS::getThisOS()).get().toString())
|
||||
{
|
||||
name = getDisplayName();
|
||||
|
|
@ -235,6 +236,7 @@ public:
|
|||
{
|
||||
copyAdditionalJavaLibs (appFolder);
|
||||
writeStringsXML (targetFolder);
|
||||
writeDeviceInfoXML (targetFolder);
|
||||
writeAppIcons (targetFolder);
|
||||
}
|
||||
|
||||
|
|
@ -999,6 +1001,9 @@ private:
|
|||
if (isInAppBillingEnabled())
|
||||
addOptJavaFolderToSourceSetsForModule (javaSourceSets, modules, "juce_product_unlocking");
|
||||
|
||||
if (isVirtualMidiEnabled())
|
||||
addOptJavaFolderToSourceSetsForModule (javaSourceSets, modules, "juce_audio_devices");
|
||||
|
||||
MemoryOutputStream mo;
|
||||
mo.setNewLineString (getNewLineString());
|
||||
|
||||
|
|
@ -1215,6 +1220,11 @@ private:
|
|||
props.add (new TextPropertyComponent (androidRemoteNotificationsConfigFile.getPropertyAsValue(), "Remote Notifications Config File", 2048, false),
|
||||
"Path to google-services.json file. This will be the file provided by Firebase when creating a new app in Firebase console.");
|
||||
|
||||
props.add (new ChoicePropertyComponent (androidEnableVirtualMidi, "Enable Virtual MIDI"),
|
||||
"When enabled, this will add entries to your application manifest declaring that your program "
|
||||
"can provide the MidiDeviceService and/or MidiUmpDeviceService."
|
||||
"This has no effect unless the juce_audio_devices module is included in the project.");
|
||||
|
||||
props.add (new TextPropertyComponent (androidManifestCustomXmlElements, "Custom Manifest XML Content", 8192, true),
|
||||
"You can specify custom AndroidManifest.xml content overriding the default one generated by Projucer. "
|
||||
"Projucer will automatically create any missing and required XML elements and attributes "
|
||||
|
|
@ -1341,6 +1351,12 @@ private:
|
|||
&& androidEnableRemoteNotifications.get();
|
||||
}
|
||||
|
||||
bool isVirtualMidiEnabled() const
|
||||
{
|
||||
return project.getEnabledModules().isModuleEnabled ("juce_audio_devices")
|
||||
&& androidEnableVirtualMidi.get();
|
||||
}
|
||||
|
||||
bool isInAppBillingEnabled() const
|
||||
{
|
||||
return project.getEnabledModules().isModuleEnabled ("juce_product_unlocking")
|
||||
|
|
@ -1395,6 +1411,58 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void writeDeviceInfoXML (const File& folder) const
|
||||
{
|
||||
const auto makeDeviceNode = [this] (XmlElement& devices)
|
||||
{
|
||||
auto* device = devices.createNewChildElement ("device");
|
||||
device->setAttribute ("manufacturer", project.getCompanyNameString());
|
||||
device->setAttribute ("product", projectName);
|
||||
|
||||
const auto deviceName = (project.getCompanyNameString().isNotEmpty() ? (project.getCompanyNameString() + " ") : "")
|
||||
+ projectName;
|
||||
device->setAttribute ("name", deviceName);
|
||||
return device;
|
||||
};
|
||||
|
||||
if (isVirtualMidiEnabled())
|
||||
{
|
||||
{
|
||||
auto path = folder.getChildFile ("app")
|
||||
.getChildFile ("src")
|
||||
.getChildFile ("main")
|
||||
.getChildFile ("res")
|
||||
.getChildFile ("xml")
|
||||
.getChildFile ("juce_midi_virtual_ump.xml");
|
||||
|
||||
auto devices = std::make_unique<XmlElement> ("devices");
|
||||
auto* device = makeDeviceNode (*devices);
|
||||
auto* port = device->createNewChildElement ("port");
|
||||
port->setAttribute ("name", "MIDI 2.0");
|
||||
|
||||
writeXmlOrThrow (*devices, path, "utf-8", 100, true);
|
||||
}
|
||||
|
||||
{
|
||||
auto path = folder.getChildFile ("app")
|
||||
.getChildFile ("src")
|
||||
.getChildFile ("main")
|
||||
.getChildFile ("res")
|
||||
.getChildFile ("xml")
|
||||
.getChildFile ("juce_midi_virtual_bytestream.xml");
|
||||
|
||||
auto devices = std::make_unique<XmlElement> ("devices");
|
||||
auto* device = makeDeviceNode (*devices);
|
||||
auto* portIn = device->createNewChildElement ("input-port");
|
||||
portIn->setAttribute ("name", "In");
|
||||
auto* portOut = device->createNewChildElement ("output-port");
|
||||
portOut->setAttribute ("name", "Out");
|
||||
|
||||
writeXmlOrThrow (*devices, path, "utf-8", 100, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeAndroidManifest (const File& folder) const
|
||||
{
|
||||
std::unique_ptr<XmlElement> manifest (createManifestXML());
|
||||
|
|
@ -1898,6 +1966,39 @@ private:
|
|||
metaData->setAttribute ("android:name", "firebase_analytics_collection_deactivated");
|
||||
metaData->setAttribute ("android:value", "true");
|
||||
}
|
||||
|
||||
if (isVirtualMidiEnabled())
|
||||
{
|
||||
{
|
||||
auto* service = application.createNewChildElement ("service");
|
||||
service->setAttribute ("android:name", "com.rmsl.juce.VirtualMidiServices$VirtualUmpService");
|
||||
service->setAttribute ("android:enabled", "false");
|
||||
service->setAttribute ("android:exported", "true");
|
||||
service->setAttribute ("android:permission", "android.permission.BIND_MIDI_DEVICE_SERVICE");
|
||||
|
||||
auto* intentFilter = service->createNewChildElement ("intent-filter");
|
||||
intentFilter->createNewChildElement ("action")->setAttribute ("android:name", "android.media.midi.MidiUmpDeviceService");
|
||||
|
||||
auto* property = service->createNewChildElement ("property");
|
||||
property->setAttribute ("android:name", "android.media.midi.MidiUmpDeviceService");
|
||||
property->setAttribute ("android:resource", "@xml/juce_midi_virtual_ump");
|
||||
}
|
||||
|
||||
{
|
||||
auto* service = application.createNewChildElement ("service");
|
||||
service->setAttribute ("android:name", "com.rmsl.juce.VirtualMidiServices$VirtualBytestreamService");
|
||||
service->setAttribute ("android:enabled", "false");
|
||||
service->setAttribute ("android:exported", "true");
|
||||
service->setAttribute ("android:permission", "android.permission.BIND_MIDI_DEVICE_SERVICE");
|
||||
|
||||
auto* intentFilter = service->createNewChildElement ("intent-filter");
|
||||
intentFilter->createNewChildElement ("action")->setAttribute ("android:name", "android.media.midi.MidiDeviceService");
|
||||
|
||||
auto* metadata = service->createNewChildElement ("meta-data");
|
||||
metadata->setAttribute ("android:name", "android.media.midi.MidiDeviceService");
|
||||
metadata->setAttribute ("android:resource", "@xml/juce_midi_virtual_bytestream");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createProviderElement (XmlElement& application) const
|
||||
|
|
|
|||
|
|
@ -268,6 +268,7 @@ namespace Ids
|
|||
DECLARE_ID (androidScreenOrientation);
|
||||
DECLARE_ID (androidExtraAssetsFolder);
|
||||
DECLARE_ID (androidStudioExePath);
|
||||
DECLARE_ID (androidEnableVirtualMidi);
|
||||
DECLARE_ID (iosDeviceFamily);
|
||||
const Identifier iPhoneScreenOrientation ("iosScreenOrientation"); // old name is confusing
|
||||
DECLARE_ID (iPadScreenOrientation);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue