| @@ -198,18 +198,17 @@ void Project::initialiseProjectValues() | |||
| displaySplashScreenValue.referTo (projectRoot, Ids::displaySplashScreen, getUndoManager(), ! ProjucerApplication::getApp().isPaidOrGPL()); | |||
| splashScreenColourValue.referTo (projectRoot, Ids::splashScreenColour, getUndoManager(), "Dark"); | |||
| reportAppUsageValue.referTo (projectRoot, Ids::reportAppUsage, getUndoManager(), ! ProjucerApplication::getApp().isPaidOrGPL()); | |||
| useAppConfigValue.referTo (projectRoot, Ids::useAppConfig, getUndoManager(), true); | |||
| addUsingNamespaceToJuceHeader.referTo (projectRoot, Ids::addUsingNamespaceToJuceHeader, getUndoManager(), true); | |||
| cppStandardValue.referTo (projectRoot, Ids::cppLanguageStandard, getUndoManager(), "14"); | |||
| headerSearchPathsValue.referTo (projectRoot, Ids::headerPath, getUndoManager()); | |||
| preprocessorDefsValue.referTo (projectRoot, Ids::defines, getUndoManager()); | |||
| userNotesValue.referTo (projectRoot, Ids::userNotes, getUndoManager()); | |||
| headerSearchPathsValue.referTo (projectRoot, Ids::headerPath, getUndoManager()); | |||
| preprocessorDefsValue.referTo (projectRoot, Ids::defines, getUndoManager()); | |||
| userNotesValue.referTo (projectRoot, Ids::userNotes, getUndoManager()); | |||
| maxBinaryFileSizeValue.referTo (projectRoot, Ids::maxBinaryFileSize, getUndoManager(), 10240 * 1024); | |||
| maxBinaryFileSizeValue.referTo (projectRoot, Ids::maxBinaryFileSize, getUndoManager(), 10240 * 1024); | |||
| // this is here for backwards compatibility with old projects using the incorrect id | |||
| if (projectRoot.hasProperty ("includeBinaryInAppConfig")) | |||
| @@ -896,29 +895,16 @@ void Project::createPropertyEditors (PropertyListBuilder& props) | |||
| "license, or are using JUCE under the GPL v3 license."); | |||
| StringPairArray description; | |||
| description.set ("Report JUCE app usage", "This option controls the collection of usage data from users of this JUCE application."); | |||
| description.set ("Display the JUCE splash screen", "This option controls the display of the standard JUCE splash screen."); | |||
| if (ProjucerApplication::getApp().isPaidOrGPL()) | |||
| { | |||
| props.add (new ChoicePropertyComponent (reportAppUsageValue, String ("Report JUCE App Usage") + " (" + licenseRequiredTagline + ")"), | |||
| description["Report JUCE app usage"] + " " + licenseRequiredInfo); | |||
| props.add (new ChoicePropertyComponent (displaySplashScreenValue, String ("Display the JUCE Splash Screen") + " (" + licenseRequiredTagline + ")"), | |||
| description["Display the JUCE splash screen"] + " " + licenseRequiredInfo); | |||
| } | |||
| else | |||
| { | |||
| StringArray options; | |||
| Array<var> vars; | |||
| options.add (licenseRequiredTagline); | |||
| vars.add (var()); | |||
| props.add (new ChoicePropertyComponent (Value(), "Report JUCE App Usage", options, vars), | |||
| description["Report JUCE app usage"] + " " + licenseRequiredInfo); | |||
| props.add (new ChoicePropertyComponent (Value(), "Display the JUCE Splash Screen", options, vars), | |||
| props.add (new ChoicePropertyComponent (Value(), "Display the JUCE Splash Screen", { licenseRequiredTagline }, {}), | |||
| description["Display the JUCE splash screen"] + " " + licenseRequiredInfo); | |||
| } | |||
| } | |||
| @@ -114,7 +114,6 @@ public: | |||
| String getBinaryDataNamespaceString() const { return binaryDataNamespaceValue.get(); } | |||
| bool shouldDisplaySplashScreen() const { return displaySplashScreenValue.get(); } | |||
| bool shouldReportAppUsage() const { return reportAppUsageValue.get(); } | |||
| String getSplashScreenColourString() const { return splashScreenColourValue.get(); } | |||
| String getCppStandardString() const { return cppStandardValue.get(); } | |||
| @@ -417,7 +416,7 @@ private: | |||
| ValueTree projectRoot { Ids::JUCERPROJECT }; | |||
| ValueWithDefault projectNameValue, projectUIDValue, projectLineFeedValue, projectTypeValue, versionValue, bundleIdentifierValue, companyNameValue, | |||
| companyCopyrightValue, companyWebsiteValue, companyEmailValue, displaySplashScreenValue, reportAppUsageValue, splashScreenColourValue, cppStandardValue, | |||
| companyCopyrightValue, companyWebsiteValue, companyEmailValue, displaySplashScreenValue, splashScreenColourValue, cppStandardValue, | |||
| headerSearchPathsValue, preprocessorDefsValue, userNotesValue, maxBinaryFileSizeValue, includeBinaryDataInJuceHeaderValue, binaryDataNamespaceValue, | |||
| compilerFlagSchemesValue, postExportShellCommandPosixValue, postExportShellCommandWinValue, useAppConfigValue, addUsingNamespaceToJuceHeader; | |||
| @@ -455,7 +455,6 @@ StringPairArray ProjectExporter::getAppConfigDefs() const | |||
| { | |||
| StringPairArray result; | |||
| result.set ("JUCE_DISPLAY_SPLASH_SCREEN", project.shouldDisplaySplashScreen() ? "1" : "0"); | |||
| result.set ("JUCE_REPORT_APP_USAGE", project.shouldReportAppUsage() ? "1" : "0"); | |||
| result.set ("JUCE_USE_DARK_SPLASH_SCREEN", project.getSplashScreenColourString() == "Dark" ? "1" : "0"); | |||
| result.set ("JUCE_PROJUCER_VERSION", "0x" + String::toHexString (ProjectInfo::versionNumber)); | |||
| @@ -452,11 +452,6 @@ private: | |||
| << "#ifndef JUCE_DISPLAY_SPLASH_SCREEN" << newLine | |||
| << " #define JUCE_DISPLAY_SPLASH_SCREEN " << (project.shouldDisplaySplashScreen() ? "1" : "0") << newLine | |||
| << "#endif" << newLine << newLine | |||
| << "#ifndef JUCE_REPORT_APP_USAGE" << newLine | |||
| << " #define JUCE_REPORT_APP_USAGE " << (project.shouldReportAppUsage() ? "1" : "0") << newLine | |||
| << "#endif" << newLine | |||
| << newLine | |||
| << "// END SECTION A" << newLine | |||
| << newLine | |||
| << "#define JUCE_USE_DARK_SPLASH_SCREEN " << (project.getSplashScreenColourString() == "Dark" ? "1" : "0") << newLine | |||
| @@ -43,7 +43,6 @@ namespace Ids | |||
| DECLARE_ID (useAppConfig); | |||
| DECLARE_ID (addUsingNamespaceToJuceHeader); | |||
| DECLARE_ID (displaySplashScreen); | |||
| DECLARE_ID (reportAppUsage); | |||
| DECLARE_ID (splashScreenColour); | |||
| DECLARE_ID (position); | |||
| DECLARE_ID (source); | |||
| @@ -49,8 +49,7 @@ namespace juce | |||
| static const int millisecondsToDisplaySplash = 2000, splashScreenFadeOutTime = 2000; | |||
| static const int splashScreenLogoWidth = 123, splashScreenLogoHeight = 63; | |||
| static uint32 splashDisplayTime = 0; | |||
| static bool splashHasStartedFading = false, appUsageReported = false; | |||
| static bool splashHasStartedFading = false; | |||
| static Rectangle<float> getLogoArea (Rectangle<float> parentRect) | |||
| { | |||
| @@ -59,175 +58,11 @@ static Rectangle<float> getLogoArea (Rectangle<float> parentRect) | |||
| .removeFromBottom ((float) splashScreenLogoHeight); | |||
| } | |||
| //============================================================================== | |||
| struct ReportingThread; | |||
| struct ReportingThreadContainer : public ChangeListener, | |||
| public DeletedAtShutdown | |||
| { | |||
| ReportingThreadContainer() {} | |||
| ~ReportingThreadContainer() override { clearSingletonInstance(); } | |||
| void sendReport (String, String&, StringPairArray&); | |||
| void changeListenerCallback (ChangeBroadcaster*) override; | |||
| std::unique_ptr<ReportingThread> reportingThread; | |||
| JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (ReportingThreadContainer) | |||
| }; | |||
| JUCE_IMPLEMENT_SINGLETON (ReportingThreadContainer) | |||
| //============================================================================== | |||
| struct ReportingThread : public Thread, | |||
| private ChangeBroadcaster | |||
| { | |||
| ReportingThread (ReportingThreadContainer& container, | |||
| String& address, | |||
| String& userAgent, | |||
| StringPairArray& parameters) | |||
| : Thread ("JUCE app usage reporting"), | |||
| threadContainer (container), | |||
| headers ("User-Agent: " + userAgent) | |||
| { | |||
| StringArray postData; | |||
| for (auto& key : parameters.getAllKeys()) | |||
| if (parameters[key].isNotEmpty()) | |||
| postData.add (key + "=" + URL::addEscapeChars (parameters[key], true)); | |||
| url = URL (address).withPOSTData (postData.joinIntoString ("&")); | |||
| addChangeListener (&threadContainer); | |||
| } | |||
| ~ReportingThread() override | |||
| { | |||
| removeChangeListener (&threadContainer); | |||
| if (webStream != nullptr) | |||
| webStream->cancel(); | |||
| stopThread (2000); | |||
| } | |||
| void run() override | |||
| { | |||
| webStream.reset (new WebInputStream (url, true)); | |||
| webStream->withExtraHeaders (headers); | |||
| webStream->connect (nullptr); | |||
| sendChangeMessage(); | |||
| } | |||
| private: | |||
| ReportingThreadContainer& threadContainer; | |||
| URL url; | |||
| String headers; | |||
| std::unique_ptr<WebInputStream> webStream; | |||
| }; | |||
| //============================================================================== | |||
| void ReportingThreadContainer::sendReport (String address, String& userAgent, StringPairArray& parameters) | |||
| { | |||
| reportingThread.reset (new ReportingThread (*this, address, userAgent, parameters)); | |||
| reportingThread->startThread(); | |||
| } | |||
| void ReportingThreadContainer::changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| reportingThread.reset(); | |||
| } | |||
| //============================================================================== | |||
| JUCESplashScreen::JUCESplashScreen (Component& parent) | |||
| { | |||
| ignoreUnused (parent); | |||
| #if JUCE_REPORT_APP_USAGE | |||
| if (! appUsageReported) | |||
| { | |||
| const ScopedTryLock appUsageReportingLock (appUsageReporting); | |||
| if (appUsageReportingLock.isLocked() && ! appUsageReported) | |||
| { | |||
| const auto deviceDescription = SystemStats::getDeviceDescription(); | |||
| const auto deviceString = SystemStats::getDeviceIdentifiers().joinIntoString (":"); | |||
| const auto deviceIdentifier = String::toHexString (deviceString.hashCode64()); | |||
| const auto osName = SystemStats::getOperatingSystemName(); | |||
| StringPairArray data; | |||
| data.set ("v", "1"); | |||
| data.set ("tid", "UA-19759318-3"); | |||
| data.set ("cid", deviceIdentifier); | |||
| data.set ("t", "event"); | |||
| data.set ("ec", "info"); | |||
| data.set ("ea", "appStarted"); | |||
| data.set ("cd1", SystemStats::getJUCEVersion()); | |||
| data.set ("cd2", osName); | |||
| data.set ("cd3", deviceDescription); | |||
| data.set ("cd4", deviceIdentifier); | |||
| String appType, appName, appVersion, appManufacturer; | |||
| #if defined(JucePlugin_Name) | |||
| appType = "Plugin"; | |||
| appName = JucePlugin_Name; | |||
| appVersion = JucePlugin_VersionString; | |||
| appManufacturer = JucePlugin_Manufacturer; | |||
| #else | |||
| if (JUCEApplicationBase::isStandaloneApp()) | |||
| { | |||
| appType = "Application"; | |||
| if (auto* app = JUCEApplicationBase::getInstance()) | |||
| { | |||
| appName = app->getApplicationName(); | |||
| appVersion = app->getApplicationVersion(); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| appType = "Library"; | |||
| } | |||
| #endif | |||
| data.set ("cd5", appType); | |||
| data.set ("cd6", appName); | |||
| data.set ("cd7", appVersion); | |||
| data.set ("cd8", appManufacturer); | |||
| data.set ("an", appName); | |||
| data.set ("av", appVersion); | |||
| auto agentCPUVendor = SystemStats::getCpuVendor(); | |||
| if (agentCPUVendor.isEmpty()) | |||
| agentCPUVendor = "CPU"; | |||
| auto agentOSName = osName.replaceCharacter ('.', '_') | |||
| .replace ("iOS", "iPhone OS"); | |||
| #if JUCE_IOS | |||
| agentOSName << " like Mac OS X"; | |||
| #endif | |||
| String userAgent; | |||
| userAgent << "Mozilla/5.0 (" | |||
| << deviceDescription << ";" | |||
| << agentCPUVendor << " " << agentOSName << ";" | |||
| << SystemStats::getDisplayLanguage() << ")"; | |||
| ReportingThreadContainer::getInstance()->sendReport ("https://www.google-analytics.com/collect", userAgent, data); | |||
| appUsageReported = true; | |||
| } | |||
| } | |||
| #else | |||
| ignoreUnused (appUsageReported); | |||
| #endif | |||
| #if JUCE_DISPLAY_SPLASH_SCREEN | |||
| if (splashDisplayTime == 0 | |||
| || Time::getMillisecondCounter() < splashDisplayTime + (uint32) millisecondsToDisplaySplash) | |||
| @@ -244,10 +79,6 @@ JUCESplashScreen::JUCESplashScreen (Component& parent) | |||
| } | |||
| } | |||
| JUCESplashScreen::~JUCESplashScreen() | |||
| { | |||
| } | |||
| std::unique_ptr<Drawable> JUCESplashScreen::getSplashScreenLogo() | |||
| { | |||
| const char* svgData = R"JUCESPLASHSCREEN( | |||
| @@ -45,7 +45,6 @@ class JUCE_API JUCESplashScreen : public Component, | |||
| { | |||
| public: | |||
| JUCESplashScreen (Component& parentToAddTo); | |||
| ~JUCESplashScreen() override; | |||
| static std::unique_ptr<Drawable> getSplashScreenLogo(); | |||
| @@ -58,7 +57,6 @@ private: | |||
| void mouseUp (const MouseEvent&) override; | |||
| std::unique_ptr<Drawable> content; | |||
| CriticalSection appUsageReporting; | |||
| ComponentAnimator fader; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JUCESplashScreen) | |||