mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Analytics: Added an new analytics module
This commit is contained in:
parent
55a917ebe5
commit
413164f46a
60 changed files with 11508 additions and 0 deletions
109
examples/AnalyticsCollection/AnalyticsCollection.jucer
Normal file
109
examples/AnalyticsCollection/AnalyticsCollection.jucer
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<JUCERPROJECT id="Z3D0EG" name="AnalyticsCollection" displaySplashScreen="0"
|
||||
reportAppUsage="0" splashScreenColour="Dark" projectType="guiapp"
|
||||
version="1.0.0" bundleIdentifier="com.yourcompany.AnalyticsCollection"
|
||||
includeBinaryInAppConfig="1" cppLanguageStandard="11" companyCopyright=""
|
||||
jucerVersion="5.1.2">
|
||||
<MAINGROUP id="aOi9Tf" name="AnalyticsCollection">
|
||||
<GROUP id="{527B2E17-B1B1-B919-CBEA-231058E23D74}" name="Source">
|
||||
<FILE id="qTLkDX" name="GoogleAnalyticsDestination.h" compile="0" resource="0"
|
||||
file="Source/GoogleAnalyticsDestination.h"/>
|
||||
<FILE id="DHs1bY" name="MainComponent.h" compile="0" resource="0" file="Source/MainComponent.h"/>
|
||||
<FILE id="dsUiEq" name="Main.cpp" compile="1" resource="0" file="Source/Main.cpp"/>
|
||||
</GROUP>
|
||||
</MAINGROUP>
|
||||
<EXPORTFORMATS>
|
||||
<XCODE_MAC targetFolder="Builds/MacOSX">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="AnalyticsCollection"
|
||||
enablePluginBinaryCopyStep="1"/>
|
||||
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="AnalyticsCollection"
|
||||
enablePluginBinaryCopyStep="1"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_analytics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</XCODE_MAC>
|
||||
<XCODE_IPHONE targetFolder="Builds/iOS" iosScreenOrientation="portraitlandscape"
|
||||
iosDeviceFamily="1,2" iPadScreenOrientation="portraitlandscape">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="AnalyticsCollection"
|
||||
enablePluginBinaryCopyStep="1"/>
|
||||
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="AnalyticsCollection"
|
||||
enablePluginBinaryCopyStep="1"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_analytics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</XCODE_IPHONE>
|
||||
<VS2017 targetFolder="Builds/VisualStudio2017">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
|
||||
isDebug="1" optimisation="1" targetName="AnalyticsCollection"
|
||||
debugInformationFormat="ProgramDatabase" enablePluginBinaryCopyStep="0"/>
|
||||
<CONFIGURATION name="Release" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
|
||||
isDebug="0" optimisation="3" targetName="AnalyticsCollection"
|
||||
debugInformationFormat="None" enablePluginBinaryCopyStep="0"
|
||||
linkTimeOptimisation="1"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_analytics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</VS2017>
|
||||
<LINUX_MAKE targetFolder="Builds/LinuxMakefile" extraDefs="JUCE_USE_CURL=1">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="AnalyticsCollection"/>
|
||||
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="AnalyticsCollection"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_analytics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</LINUX_MAKE>
|
||||
<ANDROIDSTUDIO targetFolder="Builds/Android">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" androidArchitectures="armeabi x86" isDebug="1" optimisation="1"
|
||||
targetName="AnalyticsCollection"/>
|
||||
<CONFIGURATION name="Release" androidArchitectures="" isDebug="0" optimisation="3"
|
||||
targetName="AnalyticsCollection"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_analytics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</ANDROIDSTUDIO>
|
||||
</EXPORTFORMATS>
|
||||
<MODULES>
|
||||
<MODULE id="juce_analytics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
|
||||
<MODULE id="juce_core" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
|
||||
<MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
|
||||
<MODULE id="juce_events" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
|
||||
<MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
|
||||
<MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
|
||||
</MODULES>
|
||||
<JUCEOPTIONS/>
|
||||
</JUCERPROJECT>
|
||||
1535
examples/AnalyticsCollection/Builds/Android/app/CMakeLists.txt
Normal file
1535
examples/AnalyticsCollection/Builds/Android/app/CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load diff
89
examples/AnalyticsCollection/Builds/Android/app/build.gradle
Normal file
89
examples/AnalyticsCollection/Builds/Android/app/build.gradle
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 10
|
||||
buildToolsVersion "26.0.0"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
juceSigning {
|
||||
storeFile file("${System.properties['user.home']}${File.separator}.android${File.separator}debug.keystore")
|
||||
storePassword "android"
|
||||
keyAlias "androiddebugkey"
|
||||
keyPassword "android"
|
||||
storeType "jks"
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.yourcompany.analyticscollection"
|
||||
minSdkVersion 10
|
||||
targetSdkVersion 10
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-10", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE"
|
||||
cFlags "-fsigned-char"
|
||||
cppFlags "-fsigned-char", "-std=c++11"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
initWith debug
|
||||
debuggable true
|
||||
jniDebuggable true
|
||||
signingConfig signingConfigs.juceSigning
|
||||
}
|
||||
release {
|
||||
initWith release
|
||||
debuggable false
|
||||
jniDebuggable false
|
||||
signingConfig signingConfigs.juceSigning
|
||||
}
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
debug_ {
|
||||
ndk {
|
||||
abiFilters "armeabi", "x86"
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DJUCE_BUILD_CONFIGFURATION=DEBUG", "-DCMAKE_CXX_FLAGS_DEBUG=-O0", "-DCMAKE_C_FLAGS_DEBUG=-O0"
|
||||
}
|
||||
}
|
||||
}
|
||||
release_ {
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DJUCE_BUILD_CONFIGFURATION=RELEASE", "-DCMAKE_CXX_FLAGS_RELEASE=-O3", "-DCMAKE_C_FLAGS_RELEASE=-O3"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variantFilter { variant ->
|
||||
def names = variant.flavors*.name
|
||||
if (names.contains ("debug_")
|
||||
&& variant.buildType.name != "debug") {
|
||||
setIgnore(true)
|
||||
}
|
||||
if (names.contains ("release_")
|
||||
&& variant.buildType.name != "release") {
|
||||
setIgnore(true)
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<string name="app_name">AnalyticsCollection</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0.0"
|
||||
package="com.yourcompany.analyticscollection">
|
||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/>
|
||||
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<application android:label="@string/app_name">
|
||||
<activity android:name="AnalyticsCollection" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation"
|
||||
android:screenOrientation="unspecified" android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,971 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
package com.android.vending.billing;
|
||||
/**
|
||||
* InAppBillingService is the service that provides in-app billing version 3 and beyond.
|
||||
* This service provides the following features:
|
||||
* 1. Provides a new API to get details of in-app items published for the app including
|
||||
* price, type, title and description.
|
||||
* 2. The purchase flow is synchronous and purchase information is available immediately
|
||||
* after it completes.
|
||||
* 3. Purchase information of in-app purchases is maintained within the Google Play system
|
||||
* till the purchase is consumed.
|
||||
* 4. An API to consume a purchase of an inapp item. All purchases of one-time
|
||||
* in-app items are consumable and thereafter can be purchased again.
|
||||
* 5. An API to get current purchases of the user immediately. This will not contain any
|
||||
* consumed purchases.
|
||||
*
|
||||
* All calls will give a response code with the following possible values
|
||||
* RESULT_OK = 0 - success
|
||||
* RESULT_USER_CANCELED = 1 - User pressed back or canceled a dialog
|
||||
* RESULT_SERVICE_UNAVAILABLE = 2 - The network connection is down
|
||||
* RESULT_BILLING_UNAVAILABLE = 3 - This billing API version is not supported for the type requested
|
||||
* RESULT_ITEM_UNAVAILABLE = 4 - Requested SKU is not available for purchase
|
||||
* RESULT_DEVELOPER_ERROR = 5 - Invalid arguments provided to the API
|
||||
* RESULT_ERROR = 6 - Fatal error during the API action
|
||||
* RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned
|
||||
* RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned
|
||||
*/
|
||||
public interface IInAppBillingService extends android.os.IInterface
|
||||
{
|
||||
/** Local-side IPC implementation stub class. */
|
||||
public static abstract class Stub extends android.os.Binder implements com.android.vending.billing.IInAppBillingService
|
||||
{
|
||||
private static final java.lang.String DESCRIPTOR = "com.android.vending.billing.IInAppBillingService";
|
||||
/** Construct the stub at attach it to the interface. */
|
||||
public Stub()
|
||||
{
|
||||
this.attachInterface(this, DESCRIPTOR);
|
||||
}
|
||||
/**
|
||||
* Cast an IBinder object into an com.android.vending.billing.IInAppBillingService interface,
|
||||
* generating a proxy if needed.
|
||||
*/
|
||||
public static com.android.vending.billing.IInAppBillingService asInterface(android.os.IBinder obj)
|
||||
{
|
||||
if ((obj==null)) {
|
||||
return null;
|
||||
}
|
||||
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
|
||||
if (((iin!=null)&&(iin instanceof com.android.vending.billing.IInAppBillingService))) {
|
||||
return ((com.android.vending.billing.IInAppBillingService)iin);
|
||||
}
|
||||
return new com.android.vending.billing.IInAppBillingService.Stub.Proxy(obj);
|
||||
}
|
||||
@Override public android.os.IBinder asBinder()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case INTERFACE_TRANSACTION:
|
||||
{
|
||||
reply.writeString(DESCRIPTOR);
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_isBillingSupported:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
int _result = this.isBillingSupported(_arg0, _arg1, _arg2);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(_result);
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_getSkuDetails:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
android.os.Bundle _arg3;
|
||||
if ((0!=data.readInt())) {
|
||||
_arg3 = android.os.Bundle.CREATOR.createFromParcel(data);
|
||||
}
|
||||
else {
|
||||
_arg3 = null;
|
||||
}
|
||||
android.os.Bundle _result = this.getSkuDetails(_arg0, _arg1, _arg2, _arg3);
|
||||
reply.writeNoException();
|
||||
if ((_result!=null)) {
|
||||
reply.writeInt(1);
|
||||
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
|
||||
}
|
||||
else {
|
||||
reply.writeInt(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_getBuyIntent:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
java.lang.String _arg3;
|
||||
_arg3 = data.readString();
|
||||
java.lang.String _arg4;
|
||||
_arg4 = data.readString();
|
||||
android.os.Bundle _result = this.getBuyIntent(_arg0, _arg1, _arg2, _arg3, _arg4);
|
||||
reply.writeNoException();
|
||||
if ((_result!=null)) {
|
||||
reply.writeInt(1);
|
||||
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
|
||||
}
|
||||
else {
|
||||
reply.writeInt(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_getPurchases:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
java.lang.String _arg3;
|
||||
_arg3 = data.readString();
|
||||
android.os.Bundle _result = this.getPurchases(_arg0, _arg1, _arg2, _arg3);
|
||||
reply.writeNoException();
|
||||
if ((_result!=null)) {
|
||||
reply.writeInt(1);
|
||||
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
|
||||
}
|
||||
else {
|
||||
reply.writeInt(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_consumePurchase:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
int _result = this.consumePurchase(_arg0, _arg1, _arg2);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(_result);
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_stub:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
int _result = this.stub(_arg0, _arg1, _arg2);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(_result);
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_getBuyIntentToReplaceSkus:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.util.List<java.lang.String> _arg2;
|
||||
_arg2 = data.createStringArrayList();
|
||||
java.lang.String _arg3;
|
||||
_arg3 = data.readString();
|
||||
java.lang.String _arg4;
|
||||
_arg4 = data.readString();
|
||||
java.lang.String _arg5;
|
||||
_arg5 = data.readString();
|
||||
android.os.Bundle _result = this.getBuyIntentToReplaceSkus(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
|
||||
reply.writeNoException();
|
||||
if ((_result!=null)) {
|
||||
reply.writeInt(1);
|
||||
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
|
||||
}
|
||||
else {
|
||||
reply.writeInt(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_getBuyIntentExtraParams:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
java.lang.String _arg3;
|
||||
_arg3 = data.readString();
|
||||
java.lang.String _arg4;
|
||||
_arg4 = data.readString();
|
||||
android.os.Bundle _arg5;
|
||||
if ((0!=data.readInt())) {
|
||||
_arg5 = android.os.Bundle.CREATOR.createFromParcel(data);
|
||||
}
|
||||
else {
|
||||
_arg5 = null;
|
||||
}
|
||||
android.os.Bundle _result = this.getBuyIntentExtraParams(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
|
||||
reply.writeNoException();
|
||||
if ((_result!=null)) {
|
||||
reply.writeInt(1);
|
||||
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
|
||||
}
|
||||
else {
|
||||
reply.writeInt(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_getPurchaseHistory:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
java.lang.String _arg3;
|
||||
_arg3 = data.readString();
|
||||
android.os.Bundle _arg4;
|
||||
if ((0!=data.readInt())) {
|
||||
_arg4 = android.os.Bundle.CREATOR.createFromParcel(data);
|
||||
}
|
||||
else {
|
||||
_arg4 = null;
|
||||
}
|
||||
android.os.Bundle _result = this.getPurchaseHistory(_arg0, _arg1, _arg2, _arg3, _arg4);
|
||||
reply.writeNoException();
|
||||
if ((_result!=null)) {
|
||||
reply.writeInt(1);
|
||||
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
|
||||
}
|
||||
else {
|
||||
reply.writeInt(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_isBillingSupportedExtraParams:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int _arg0;
|
||||
_arg0 = data.readInt();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
android.os.Bundle _arg3;
|
||||
if ((0!=data.readInt())) {
|
||||
_arg3 = android.os.Bundle.CREATOR.createFromParcel(data);
|
||||
}
|
||||
else {
|
||||
_arg3 = null;
|
||||
}
|
||||
int _result = this.isBillingSupportedExtraParams(_arg0, _arg1, _arg2, _arg3);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(_result);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onTransact(code, data, reply, flags);
|
||||
}
|
||||
private static class Proxy implements com.android.vending.billing.IInAppBillingService
|
||||
{
|
||||
private android.os.IBinder mRemote;
|
||||
Proxy(android.os.IBinder remote)
|
||||
{
|
||||
mRemote = remote;
|
||||
}
|
||||
@Override public android.os.IBinder asBinder()
|
||||
{
|
||||
return mRemote;
|
||||
}
|
||||
public java.lang.String getInterfaceDescriptor()
|
||||
{
|
||||
return DESCRIPTOR;
|
||||
}
|
||||
@Override public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
int _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeString(type);
|
||||
mRemote.transact(Stub.TRANSACTION_isBillingSupported, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
_result = _reply.readInt();
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
/**
|
||||
* Provides details of a list of SKUs
|
||||
* Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
|
||||
* with a list JSON strings containing the productId, price, title and description.
|
||||
* This API can be called with a maximum of 20 SKUs.
|
||||
* @param apiVersion billing API version that the app is using
|
||||
* @param packageName the package name of the calling app
|
||||
* @param type of the in-app items ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
|
||||
* on failures.
|
||||
* "DETAILS_LIST" with a StringArrayList containing purchase information
|
||||
* in JSON format similar to:
|
||||
* '{ "productId" : "exampleSku",
|
||||
* "type" : "inapp",
|
||||
* "price" : "$5.00",
|
||||
* "price_currency": "USD",
|
||||
* "price_amount_micros": 5000000,
|
||||
* "title : "Example Title",
|
||||
* "description" : "This is an example description" }'
|
||||
*/
|
||||
@Override public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
android.os.Bundle _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeString(type);
|
||||
if ((skusBundle!=null)) {
|
||||
_data.writeInt(1);
|
||||
skusBundle.writeToParcel(_data, 0);
|
||||
}
|
||||
else {
|
||||
_data.writeInt(0);
|
||||
}
|
||||
mRemote.transact(Stub.TRANSACTION_getSkuDetails, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
if ((0!=_reply.readInt())) {
|
||||
_result = android.os.Bundle.CREATOR.createFromParcel(_reply);
|
||||
}
|
||||
else {
|
||||
_result = null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
/**
|
||||
* Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
|
||||
* the type, a unique purchase token and an optional developer payload.
|
||||
* @param apiVersion billing API version that the app is using
|
||||
* @param packageName package name of the calling app
|
||||
* @param sku the SKU of the in-app item as published in the developer console
|
||||
* @param type of the in-app item being purchased ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param developerPayload optional argument to be sent back with the purchase information
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
|
||||
* on failures.
|
||||
* "BUY_INTENT" - PendingIntent to start the purchase flow
|
||||
*
|
||||
* The Pending intent should be launched with startIntentSenderForResult. When purchase flow
|
||||
* has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
|
||||
* If the purchase is successful, the result data will contain the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
|
||||
* codes on failures.
|
||||
* "INAPP_PURCHASE_DATA" - String in JSON format similar to
|
||||
* '{"orderId":"12999763169054705758.1371079406387615",
|
||||
* "packageName":"com.example.app",
|
||||
* "productId":"exampleSku",
|
||||
* "purchaseTime":1345678900000,
|
||||
* "purchaseToken" : "122333444455555",
|
||||
* "developerPayload":"example developer payload" }'
|
||||
* "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
|
||||
* was signed with the private key of the developer
|
||||
*/
|
||||
@Override public android.os.Bundle getBuyIntent(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
android.os.Bundle _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeString(sku);
|
||||
_data.writeString(type);
|
||||
_data.writeString(developerPayload);
|
||||
mRemote.transact(Stub.TRANSACTION_getBuyIntent, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
if ((0!=_reply.readInt())) {
|
||||
_result = android.os.Bundle.CREATOR.createFromParcel(_reply);
|
||||
}
|
||||
else {
|
||||
_result = null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
/**
|
||||
* Returns the current SKUs owned by the user of the type and package name specified along with
|
||||
* purchase information and a signature of the data to be validated.
|
||||
* This will return all SKUs that have been purchased in V3 and managed items purchased using
|
||||
* V1 and V2 that have not been consumed.
|
||||
* @param apiVersion billing API version that the app is using
|
||||
* @param packageName package name of the calling app
|
||||
* @param type of the in-app items being requested ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param continuationToken to be set as null for the first call, if the number of owned
|
||||
* skus are too many, a continuationToken is returned in the response bundle.
|
||||
* This method can be called again with the continuation token to get the next set of
|
||||
* owned skus.
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
|
||||
on failures.
|
||||
* "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
|
||||
* "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
|
||||
* "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
|
||||
* of the purchase information
|
||||
* "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
|
||||
* next set of in-app purchases. Only set if the
|
||||
* user has more owned skus than the current list.
|
||||
*/
|
||||
@Override public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
android.os.Bundle _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeString(type);
|
||||
_data.writeString(continuationToken);
|
||||
mRemote.transact(Stub.TRANSACTION_getPurchases, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
if ((0!=_reply.readInt())) {
|
||||
_result = android.os.Bundle.CREATOR.createFromParcel(_reply);
|
||||
}
|
||||
else {
|
||||
_result = null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
@Override public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
int _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeString(purchaseToken);
|
||||
mRemote.transact(Stub.TRANSACTION_consumePurchase, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
_result = _reply.readInt();
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
@Override public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
int _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeString(type);
|
||||
mRemote.transact(Stub.TRANSACTION_stub, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
_result = _reply.readInt();
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
/**
|
||||
* Returns a pending intent to launch the purchase flow for upgrading or downgrading a
|
||||
* subscription. The existing owned SKU(s) should be provided along with the new SKU that
|
||||
* the user is upgrading or downgrading to.
|
||||
* @param apiVersion billing API version that the app is using, must be 5 or later
|
||||
* @param packageName package name of the calling app
|
||||
* @param oldSkus the SKU(s) that the user is upgrading or downgrading from,
|
||||
* if null or empty this method will behave like {@link #getBuyIntent}
|
||||
* @param newSku the SKU that the user is upgrading or downgrading to
|
||||
* @param type of the item being purchased, currently must be "subs"
|
||||
* @param developerPayload optional argument to be sent back with the purchase information
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
|
||||
* on failures.
|
||||
* "BUY_INTENT" - PendingIntent to start the purchase flow
|
||||
*
|
||||
* The Pending intent should be launched with startIntentSenderForResult. When purchase flow
|
||||
* has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
|
||||
* If the purchase is successful, the result data will contain the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
|
||||
* codes on failures.
|
||||
* "INAPP_PURCHASE_DATA" - String in JSON format similar to
|
||||
* '{"orderId":"12999763169054705758.1371079406387615",
|
||||
* "packageName":"com.example.app",
|
||||
* "productId":"exampleSku",
|
||||
* "purchaseTime":1345678900000,
|
||||
* "purchaseToken" : "122333444455555",
|
||||
* "developerPayload":"example developer payload" }'
|
||||
* "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
|
||||
* was signed with the private key of the developer
|
||||
*/
|
||||
@Override public android.os.Bundle getBuyIntentToReplaceSkus(int apiVersion, java.lang.String packageName, java.util.List<java.lang.String> oldSkus, java.lang.String newSku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
android.os.Bundle _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeStringList(oldSkus);
|
||||
_data.writeString(newSku);
|
||||
_data.writeString(type);
|
||||
_data.writeString(developerPayload);
|
||||
mRemote.transact(Stub.TRANSACTION_getBuyIntentToReplaceSkus, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
if ((0!=_reply.readInt())) {
|
||||
_result = android.os.Bundle.CREATOR.createFromParcel(_reply);
|
||||
}
|
||||
else {
|
||||
_result = null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
/**
|
||||
* Returns a pending intent to launch the purchase flow for an in-app item. This method is
|
||||
* a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams}
|
||||
* parameter. This parameter is a Bundle of optional keys and values that affect the
|
||||
* operation of the method.
|
||||
* @param apiVersion billing API version that the app is using, must be 6 or later
|
||||
* @param packageName package name of the calling app
|
||||
* @param sku the SKU of the in-app item as published in the developer console
|
||||
* @param type of the in-app item being purchased ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param developerPayload optional argument to be sent back with the purchase information
|
||||
* @extraParams a Bundle with the following optional keys:
|
||||
* "skusToReplace" - List<String> - an optional list of SKUs that the user is
|
||||
* upgrading or downgrading from.
|
||||
* Pass this field if the purchase is upgrading or downgrading
|
||||
* existing subscriptions.
|
||||
* The specified SKUs are replaced with the SKUs that the user is
|
||||
* purchasing. Google Play replaces the specified SKUs at the start of
|
||||
* the next billing cycle.
|
||||
* "replaceSkusProration" - Boolean - whether the user should be credited for any unused
|
||||
* subscription time on the SKUs they are upgrading or downgrading.
|
||||
* If you set this field to true, Google Play swaps out the old SKUs
|
||||
* and credits the user with the unused value of their subscription
|
||||
* time on a pro-rated basis.
|
||||
* Google Play applies this credit to the new subscription, and does
|
||||
* not begin billing the user for the new subscription until after
|
||||
* the credit is used up.
|
||||
* If you set this field to false, the user does not receive credit for
|
||||
* any unused subscription time and the recurrence date does not
|
||||
* change.
|
||||
* Default value is true. Ignored if you do not pass skusToReplace.
|
||||
* "accountId" - String - an optional obfuscated string that is uniquely
|
||||
* associated with the user's account in your app.
|
||||
* If you pass this value, Google Play can use it to detect irregular
|
||||
* activity, such as many devices making purchases on the same
|
||||
* account in a short period of time.
|
||||
* Do not use the developer ID or the user's Google ID for this field.
|
||||
* In addition, this field should not contain the user's ID in
|
||||
* cleartext.
|
||||
* We recommend that you use a one-way hash to generate a string from
|
||||
* the user's ID, and store the hashed string in this field.
|
||||
* "vr" - Boolean - an optional flag indicating whether the returned intent
|
||||
* should start a VR purchase flow. The apiVersion must also be 7 or
|
||||
* later to use this flag.
|
||||
*/
|
||||
@Override public android.os.Bundle getBuyIntentExtraParams(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload, android.os.Bundle extraParams) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
android.os.Bundle _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeString(sku);
|
||||
_data.writeString(type);
|
||||
_data.writeString(developerPayload);
|
||||
if ((extraParams!=null)) {
|
||||
_data.writeInt(1);
|
||||
extraParams.writeToParcel(_data, 0);
|
||||
}
|
||||
else {
|
||||
_data.writeInt(0);
|
||||
}
|
||||
mRemote.transact(Stub.TRANSACTION_getBuyIntentExtraParams, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
if ((0!=_reply.readInt())) {
|
||||
_result = android.os.Bundle.CREATOR.createFromParcel(_reply);
|
||||
}
|
||||
else {
|
||||
_result = null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
/**
|
||||
* Returns the most recent purchase made by the user for each SKU, even if that purchase is
|
||||
* expired, canceled, or consumed.
|
||||
* @param apiVersion billing API version that the app is using, must be 6 or later
|
||||
* @param packageName package name of the calling app
|
||||
* @param type of the in-app items being requested ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param continuationToken to be set as null for the first call, if the number of owned
|
||||
* skus is too large, a continuationToken is returned in the response bundle.
|
||||
* This method can be called again with the continuation token to get the next set of
|
||||
* owned skus.
|
||||
* @param extraParams a Bundle with extra params that would be appended into http request
|
||||
* query string. Not used at this moment. Reserved for future functionality.
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value: RESULT_OK(0) if success,
|
||||
* {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures.
|
||||
*
|
||||
* "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs
|
||||
* "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information
|
||||
* "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures
|
||||
* of the purchase information
|
||||
* "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
|
||||
* next set of in-app purchases. Only set if the
|
||||
* user has more owned skus than the current list.
|
||||
*/
|
||||
@Override public android.os.Bundle getPurchaseHistory(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken, android.os.Bundle extraParams) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
android.os.Bundle _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeString(type);
|
||||
_data.writeString(continuationToken);
|
||||
if ((extraParams!=null)) {
|
||||
_data.writeInt(1);
|
||||
extraParams.writeToParcel(_data, 0);
|
||||
}
|
||||
else {
|
||||
_data.writeInt(0);
|
||||
}
|
||||
mRemote.transact(Stub.TRANSACTION_getPurchaseHistory, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
if ((0!=_reply.readInt())) {
|
||||
_result = android.os.Bundle.CREATOR.createFromParcel(_reply);
|
||||
}
|
||||
else {
|
||||
_result = null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
@Override public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
int _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeInt(apiVersion);
|
||||
_data.writeString(packageName);
|
||||
_data.writeString(type);
|
||||
if ((extraParams!=null)) {
|
||||
_data.writeInt(1);
|
||||
extraParams.writeToParcel(_data, 0);
|
||||
}
|
||||
else {
|
||||
_data.writeInt(0);
|
||||
}
|
||||
mRemote.transact(Stub.TRANSACTION_isBillingSupportedExtraParams, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
_result = _reply.readInt();
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
}
|
||||
static final int TRANSACTION_isBillingSupported = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
|
||||
static final int TRANSACTION_getSkuDetails = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
|
||||
static final int TRANSACTION_getBuyIntent = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
|
||||
static final int TRANSACTION_getPurchases = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
|
||||
static final int TRANSACTION_consumePurchase = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
|
||||
static final int TRANSACTION_stub = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
|
||||
static final int TRANSACTION_getBuyIntentToReplaceSkus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
|
||||
static final int TRANSACTION_getBuyIntentExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
|
||||
static final int TRANSACTION_getPurchaseHistory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
|
||||
static final int TRANSACTION_isBillingSupportedExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9);
|
||||
}
|
||||
public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException;
|
||||
/**
|
||||
* Provides details of a list of SKUs
|
||||
* Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
|
||||
* with a list JSON strings containing the productId, price, title and description.
|
||||
* This API can be called with a maximum of 20 SKUs.
|
||||
* @param apiVersion billing API version that the app is using
|
||||
* @param packageName the package name of the calling app
|
||||
* @param type of the in-app items ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
|
||||
* on failures.
|
||||
* "DETAILS_LIST" with a StringArrayList containing purchase information
|
||||
* in JSON format similar to:
|
||||
* '{ "productId" : "exampleSku",
|
||||
* "type" : "inapp",
|
||||
* "price" : "$5.00",
|
||||
* "price_currency": "USD",
|
||||
* "price_amount_micros": 5000000,
|
||||
* "title : "Example Title",
|
||||
* "description" : "This is an example description" }'
|
||||
*/
|
||||
public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException;
|
||||
/**
|
||||
* Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
|
||||
* the type, a unique purchase token and an optional developer payload.
|
||||
* @param apiVersion billing API version that the app is using
|
||||
* @param packageName package name of the calling app
|
||||
* @param sku the SKU of the in-app item as published in the developer console
|
||||
* @param type of the in-app item being purchased ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param developerPayload optional argument to be sent back with the purchase information
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
|
||||
* on failures.
|
||||
* "BUY_INTENT" - PendingIntent to start the purchase flow
|
||||
*
|
||||
* The Pending intent should be launched with startIntentSenderForResult. When purchase flow
|
||||
* has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
|
||||
* If the purchase is successful, the result data will contain the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
|
||||
* codes on failures.
|
||||
* "INAPP_PURCHASE_DATA" - String in JSON format similar to
|
||||
* '{"orderId":"12999763169054705758.1371079406387615",
|
||||
* "packageName":"com.example.app",
|
||||
* "productId":"exampleSku",
|
||||
* "purchaseTime":1345678900000,
|
||||
* "purchaseToken" : "122333444455555",
|
||||
* "developerPayload":"example developer payload" }'
|
||||
* "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
|
||||
* was signed with the private key of the developer
|
||||
*/
|
||||
public android.os.Bundle getBuyIntent(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException;
|
||||
/**
|
||||
* Returns the current SKUs owned by the user of the type and package name specified along with
|
||||
* purchase information and a signature of the data to be validated.
|
||||
* This will return all SKUs that have been purchased in V3 and managed items purchased using
|
||||
* V1 and V2 that have not been consumed.
|
||||
* @param apiVersion billing API version that the app is using
|
||||
* @param packageName package name of the calling app
|
||||
* @param type of the in-app items being requested ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param continuationToken to be set as null for the first call, if the number of owned
|
||||
* skus are too many, a continuationToken is returned in the response bundle.
|
||||
* This method can be called again with the continuation token to get the next set of
|
||||
* owned skus.
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
|
||||
on failures.
|
||||
* "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
|
||||
* "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
|
||||
* "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
|
||||
* of the purchase information
|
||||
* "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
|
||||
* next set of in-app purchases. Only set if the
|
||||
* user has more owned skus than the current list.
|
||||
*/
|
||||
public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException;
|
||||
public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException;
|
||||
public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException;
|
||||
/**
|
||||
* Returns a pending intent to launch the purchase flow for upgrading or downgrading a
|
||||
* subscription. The existing owned SKU(s) should be provided along with the new SKU that
|
||||
* the user is upgrading or downgrading to.
|
||||
* @param apiVersion billing API version that the app is using, must be 5 or later
|
||||
* @param packageName package name of the calling app
|
||||
* @param oldSkus the SKU(s) that the user is upgrading or downgrading from,
|
||||
* if null or empty this method will behave like {@link #getBuyIntent}
|
||||
* @param newSku the SKU that the user is upgrading or downgrading to
|
||||
* @param type of the item being purchased, currently must be "subs"
|
||||
* @param developerPayload optional argument to be sent back with the purchase information
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
|
||||
* on failures.
|
||||
* "BUY_INTENT" - PendingIntent to start the purchase flow
|
||||
*
|
||||
* The Pending intent should be launched with startIntentSenderForResult. When purchase flow
|
||||
* has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
|
||||
* If the purchase is successful, the result data will contain the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
|
||||
* codes on failures.
|
||||
* "INAPP_PURCHASE_DATA" - String in JSON format similar to
|
||||
* '{"orderId":"12999763169054705758.1371079406387615",
|
||||
* "packageName":"com.example.app",
|
||||
* "productId":"exampleSku",
|
||||
* "purchaseTime":1345678900000,
|
||||
* "purchaseToken" : "122333444455555",
|
||||
* "developerPayload":"example developer payload" }'
|
||||
* "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
|
||||
* was signed with the private key of the developer
|
||||
*/
|
||||
public android.os.Bundle getBuyIntentToReplaceSkus(int apiVersion, java.lang.String packageName, java.util.List<java.lang.String> oldSkus, java.lang.String newSku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException;
|
||||
/**
|
||||
* Returns a pending intent to launch the purchase flow for an in-app item. This method is
|
||||
* a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams}
|
||||
* parameter. This parameter is a Bundle of optional keys and values that affect the
|
||||
* operation of the method.
|
||||
* @param apiVersion billing API version that the app is using, must be 6 or later
|
||||
* @param packageName package name of the calling app
|
||||
* @param sku the SKU of the in-app item as published in the developer console
|
||||
* @param type of the in-app item being purchased ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param developerPayload optional argument to be sent back with the purchase information
|
||||
* @extraParams a Bundle with the following optional keys:
|
||||
* "skusToReplace" - List<String> - an optional list of SKUs that the user is
|
||||
* upgrading or downgrading from.
|
||||
* Pass this field if the purchase is upgrading or downgrading
|
||||
* existing subscriptions.
|
||||
* The specified SKUs are replaced with the SKUs that the user is
|
||||
* purchasing. Google Play replaces the specified SKUs at the start of
|
||||
* the next billing cycle.
|
||||
* "replaceSkusProration" - Boolean - whether the user should be credited for any unused
|
||||
* subscription time on the SKUs they are upgrading or downgrading.
|
||||
* If you set this field to true, Google Play swaps out the old SKUs
|
||||
* and credits the user with the unused value of their subscription
|
||||
* time on a pro-rated basis.
|
||||
* Google Play applies this credit to the new subscription, and does
|
||||
* not begin billing the user for the new subscription until after
|
||||
* the credit is used up.
|
||||
* If you set this field to false, the user does not receive credit for
|
||||
* any unused subscription time and the recurrence date does not
|
||||
* change.
|
||||
* Default value is true. Ignored if you do not pass skusToReplace.
|
||||
* "accountId" - String - an optional obfuscated string that is uniquely
|
||||
* associated with the user's account in your app.
|
||||
* If you pass this value, Google Play can use it to detect irregular
|
||||
* activity, such as many devices making purchases on the same
|
||||
* account in a short period of time.
|
||||
* Do not use the developer ID or the user's Google ID for this field.
|
||||
* In addition, this field should not contain the user's ID in
|
||||
* cleartext.
|
||||
* We recommend that you use a one-way hash to generate a string from
|
||||
* the user's ID, and store the hashed string in this field.
|
||||
* "vr" - Boolean - an optional flag indicating whether the returned intent
|
||||
* should start a VR purchase flow. The apiVersion must also be 7 or
|
||||
* later to use this flag.
|
||||
*/
|
||||
public android.os.Bundle getBuyIntentExtraParams(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload, android.os.Bundle extraParams) throws android.os.RemoteException;
|
||||
/**
|
||||
* Returns the most recent purchase made by the user for each SKU, even if that purchase is
|
||||
* expired, canceled, or consumed.
|
||||
* @param apiVersion billing API version that the app is using, must be 6 or later
|
||||
* @param packageName package name of the calling app
|
||||
* @param type of the in-app items being requested ("inapp" for one-time purchases
|
||||
* and "subs" for subscriptions)
|
||||
* @param continuationToken to be set as null for the first call, if the number of owned
|
||||
* skus is too large, a continuationToken is returned in the response bundle.
|
||||
* This method can be called again with the continuation token to get the next set of
|
||||
* owned skus.
|
||||
* @param extraParams a Bundle with extra params that would be appended into http request
|
||||
* query string. Not used at this moment. Reserved for future functionality.
|
||||
* @return Bundle containing the following key-value pairs
|
||||
* "RESPONSE_CODE" with int value: RESULT_OK(0) if success,
|
||||
* {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures.
|
||||
*
|
||||
* "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs
|
||||
* "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information
|
||||
* "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures
|
||||
* of the purchase information
|
||||
* "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
|
||||
* next set of in-app purchases. Only set if the
|
||||
* user has more owned skus than the current list.
|
||||
*/
|
||||
public android.os.Bundle getPurchaseHistory(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken, android.os.Bundle extraParams) throws android.os.RemoteException;
|
||||
public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<string name="app_name">AnalyticsCollection</string>
|
||||
</resources>
|
||||
14
examples/AnalyticsCollection/Builds/Android/build.gradle
Normal file
14
examples/AnalyticsCollection/Builds/Android/build.gradle
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
202
examples/AnalyticsCollection/Builds/Android/gradle/wrapper/LICENSE-for-gradlewrapper.txt
vendored
Normal file
202
examples/AnalyticsCollection/Builds/Android/gradle/wrapper/LICENSE-for-gradlewrapper.txt
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
BIN
examples/AnalyticsCollection/Builds/Android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
examples/AnalyticsCollection/Builds/Android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
1
examples/AnalyticsCollection/Builds/Android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
1
examples/AnalyticsCollection/Builds/Android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
|
||||
160
examples/AnalyticsCollection/Builds/Android/gradlew
vendored
Executable file
160
examples/AnalyticsCollection/Builds/Android/gradlew
vendored
Executable file
|
|
@ -0,0 +1,160 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
examples/AnalyticsCollection/Builds/Android/gradlew.bat
vendored
Normal file
90
examples/AnalyticsCollection/Builds/Android/gradlew.bat
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
|
|
@ -0,0 +1 @@
|
|||
include ':app'
|
||||
135
examples/AnalyticsCollection/Builds/LinuxMakefile/Makefile
Normal file
135
examples/AnalyticsCollection/Builds/LinuxMakefile/Makefile
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
# Automatically generated makefile, created by the Projucer
|
||||
# Don't edit this file! Your changes will be overwritten when you re-save the Projucer project!
|
||||
|
||||
# build with "V=1" for verbose builds
|
||||
ifeq ($(V), 1)
|
||||
V_AT =
|
||||
else
|
||||
V_AT = @
|
||||
endif
|
||||
|
||||
# (this disables dependency generation if multiple architectures are set)
|
||||
DEPFLAGS := $(if $(word 2, $(TARGET_ARCH)), , -MMD)
|
||||
|
||||
ifndef STRIP
|
||||
STRIP=strip
|
||||
endif
|
||||
|
||||
ifndef AR
|
||||
AR=ar
|
||||
endif
|
||||
|
||||
ifndef CONFIG
|
||||
CONFIG=Debug
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG),Debug)
|
||||
JUCE_BINDIR := build
|
||||
JUCE_LIBDIR := build
|
||||
JUCE_OBJDIR := build/intermediate/Debug
|
||||
JUCE_OUTDIR := build
|
||||
|
||||
ifeq ($(TARGET_ARCH),)
|
||||
TARGET_ARCH := -march=native
|
||||
endif
|
||||
|
||||
JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCE_USE_CURL=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
|
||||
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0
|
||||
JUCE_TARGET_APP := AnalyticsCollection
|
||||
|
||||
JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS)
|
||||
JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++11 $(CXXFLAGS)
|
||||
JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs freetype2 libcurl x11 xext xinerama) -ldl -lpthread -lrt $(LDFLAGS)
|
||||
|
||||
CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG),Release)
|
||||
JUCE_BINDIR := build
|
||||
JUCE_LIBDIR := build
|
||||
JUCE_OBJDIR := build/intermediate/Release
|
||||
JUCE_OUTDIR := build
|
||||
|
||||
ifeq ($(TARGET_ARCH),)
|
||||
TARGET_ARCH := -march=native
|
||||
endif
|
||||
|
||||
JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCE_USE_CURL=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags freetype2 libcurl x11 xext xinerama) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
|
||||
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0
|
||||
JUCE_TARGET_APP := AnalyticsCollection
|
||||
|
||||
JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 $(CFLAGS)
|
||||
JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++11 $(CXXFLAGS)
|
||||
JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs freetype2 libcurl x11 xext xinerama) -fvisibility=hidden -ldl -lpthread -lrt $(LDFLAGS)
|
||||
|
||||
CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR)
|
||||
endif
|
||||
|
||||
OBJECTS_APP := \
|
||||
$(JUCE_OBJDIR)/Main_90ebc5c2.o \
|
||||
$(JUCE_OBJDIR)/include_juce_analytics_f8e9fa94.o \
|
||||
$(JUCE_OBJDIR)/include_juce_core_f26d17db.o \
|
||||
$(JUCE_OBJDIR)/include_juce_data_structures_7471b1e3.o \
|
||||
$(JUCE_OBJDIR)/include_juce_events_fd7d695.o \
|
||||
$(JUCE_OBJDIR)/include_juce_graphics_f817e147.o \
|
||||
$(JUCE_OBJDIR)/include_juce_gui_basics_e3f79785.o \
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
all : $(JUCE_OUTDIR)/$(JUCE_TARGET_APP)
|
||||
|
||||
$(JUCE_OUTDIR)/$(JUCE_TARGET_APP) : check-pkg-config $(OBJECTS_APP) $(RESOURCES)
|
||||
@echo Linking "AnalyticsCollection - App"
|
||||
-$(V_AT)mkdir -p $(JUCE_BINDIR)
|
||||
-$(V_AT)mkdir -p $(JUCE_LIBDIR)
|
||||
-$(V_AT)mkdir -p $(JUCE_OUTDIR)
|
||||
$(V_AT)$(CXX) -o $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(OBJECTS_APP) $(JUCE_LDFLAGS) $(RESOURCES) $(TARGET_ARCH)
|
||||
|
||||
$(JUCE_OBJDIR)/Main_90ebc5c2.o: ../../Source/Main.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling Main.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_analytics_f8e9fa94.o: ../../JuceLibraryCode/include_juce_analytics.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_analytics.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_core_f26d17db.o: ../../JuceLibraryCode/include_juce_core.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_core.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_data_structures_7471b1e3.o: ../../JuceLibraryCode/include_juce_data_structures.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_data_structures.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_events_fd7d695.o: ../../JuceLibraryCode/include_juce_events.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_events.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_graphics_f817e147.o: ../../JuceLibraryCode/include_juce_graphics.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_graphics.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_gui_basics_e3f79785.o: ../../JuceLibraryCode/include_juce_gui_basics.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_gui_basics.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
check-pkg-config:
|
||||
@command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; }
|
||||
@pkg-config --print-errors freetype2 libcurl x11 xext xinerama
|
||||
|
||||
clean:
|
||||
@echo Cleaning AnalyticsCollection
|
||||
$(V_AT)$(CLEANCMD)
|
||||
|
||||
strip:
|
||||
@echo Stripping AnalyticsCollection
|
||||
-$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET)
|
||||
|
||||
-include $(OBJECTS_APP:%.o=%.d)
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
95AA57DF380DDDCD099D4000 = {isa = PBXBuildFile; fileRef = 707149C59A1AF9752E428B97; };
|
||||
B45E888BC48139CA81112E4A = {isa = PBXBuildFile; fileRef = 570EA8E9B2BD490DAA35F86E; };
|
||||
375013DDDA026F2709E4FDAD = {isa = PBXBuildFile; fileRef = C858CF44E96D416E4B6B9266; };
|
||||
877F68400FB5A15B39719C61 = {isa = PBXBuildFile; fileRef = 08EEB00E1779867598046EB6; };
|
||||
38EE4929FFB8B83FB37B6E73 = {isa = PBXBuildFile; fileRef = FBCE051A0BA6C9FA3E64B47B; };
|
||||
A0DA914E3E16F49D60A5A47F = {isa = PBXBuildFile; fileRef = 3D44D3C7CC1020729BBF62BB; };
|
||||
D293FC19C031441D146F2410 = {isa = PBXBuildFile; fileRef = 6A86C9751E9DCFA62D4562DB; };
|
||||
962036B1BB2EDB0F9D53E125 = {isa = PBXBuildFile; fileRef = 33B9806EFA95DA05ACD9344E; };
|
||||
6297B7A712B1E5A74311F162 = {isa = PBXBuildFile; fileRef = 5DC0FF6BC4AE24FABC41F20E; };
|
||||
132F9FBC9EB36AF2E755325D = {isa = PBXBuildFile; fileRef = AD2CFF58DA5E1C6EDF9CC399; };
|
||||
805CDCC5840B0D713C286826 = {isa = PBXBuildFile; fileRef = A0DDFB3559C431E96EC59392; };
|
||||
C09B5A3CD0643CF37C9CF851 = {isa = PBXBuildFile; fileRef = 61FADB63565026F559F43F3B; };
|
||||
A1DF340E80EC501B1DBE75A0 = {isa = PBXBuildFile; fileRef = 65311EED96DCA9B62EBFEA04; };
|
||||
02589D465A73E0112B97BD3A = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
|
||||
08EEB00E1779867598046EB6 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||
1AA9DA887BE127DCED5228BB = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
|
||||
33B9806EFA95DA05ACD9344E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_analytics.cpp"; path = "../../JuceLibraryCode/include_juce_analytics.cpp"; sourceTree = "SOURCE_ROOT"; };
|
||||
3D44D3C7CC1020729BBF62BB = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; };
|
||||
5219A3D3BECB8C7135C90377 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; path = "../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; };
|
||||
570EA8E9B2BD490DAA35F86E = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
|
||||
5DC0FF6BC4AE24FABC41F20E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_core.mm"; path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
61FADB63565026F559F43F3B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
65311EED96DCA9B62EBFEA04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_basics.mm"; path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
6A86C9751E9DCFA62D4562DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Main.cpp; path = ../../Source/Main.cpp; sourceTree = "SOURCE_ROOT"; };
|
||||
707149C59A1AF9752E428B97 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnalyticsCollection.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
|
||||
7A9FA859A2C2AE9FDDC99AD9 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; };
|
||||
886AEA380A40C905503764EB = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_graphics"; path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
|
||||
8A74F3F7422C89A897D93397 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
|
||||
8B927F72BA8726A064560942 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GoogleAnalyticsDestination.h; path = ../../Source/GoogleAnalyticsDestination.h; sourceTree = "SOURCE_ROOT"; };
|
||||
91208A06115D573563996967 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
|
||||
996BEF5ADCE2EC85EB9F637F = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_data_structures"; path = "../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
|
||||
A0DDFB3559C431E96EC59392 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_events.mm"; path = "../../JuceLibraryCode/include_juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
AD2CFF58DA5E1C6EDF9CC399 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
C858CF44E96D416E4B6B9266 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
D352CDB4CA7E8B21FAA83B8C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainComponent.h; path = ../../Source/MainComponent.h; sourceTree = "SOURCE_ROOT"; };
|
||||
F2CF007AA4C90AC7A5AD1604 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_analytics"; path = "../../../../modules/juce_analytics"; sourceTree = "SOURCE_ROOT"; };
|
||||
FBCE051A0BA6C9FA3E64B47B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
D269FA28B5D6012AEFE0BF20 = {isa = PBXGroup; children = (
|
||||
8B927F72BA8726A064560942,
|
||||
D352CDB4CA7E8B21FAA83B8C,
|
||||
6A86C9751E9DCFA62D4562DB, ); name = Source; sourceTree = "<group>"; };
|
||||
2B971235E85DF9D98B6FC8AF = {isa = PBXGroup; children = (
|
||||
D269FA28B5D6012AEFE0BF20, ); name = AnalyticsCollection; sourceTree = "<group>"; };
|
||||
0B35DCE65DF34DECBF1D8118 = {isa = PBXGroup; children = (
|
||||
F2CF007AA4C90AC7A5AD1604,
|
||||
02589D465A73E0112B97BD3A,
|
||||
996BEF5ADCE2EC85EB9F637F,
|
||||
1AA9DA887BE127DCED5228BB,
|
||||
886AEA380A40C905503764EB,
|
||||
5219A3D3BECB8C7135C90377, ); name = "Juce Modules"; sourceTree = "<group>"; };
|
||||
B24D9AE60E0CE5D1A75693B5 = {isa = PBXGroup; children = (
|
||||
8A74F3F7422C89A897D93397,
|
||||
33B9806EFA95DA05ACD9344E,
|
||||
5DC0FF6BC4AE24FABC41F20E,
|
||||
AD2CFF58DA5E1C6EDF9CC399,
|
||||
A0DDFB3559C431E96EC59392,
|
||||
61FADB63565026F559F43F3B,
|
||||
65311EED96DCA9B62EBFEA04,
|
||||
91208A06115D573563996967, ); name = "Juce Library Code"; sourceTree = "<group>"; };
|
||||
782C3BD0C802236A266FDEDD = {isa = PBXGroup; children = (
|
||||
7A9FA859A2C2AE9FDDC99AD9,
|
||||
3D44D3C7CC1020729BBF62BB, ); name = Resources; sourceTree = "<group>"; };
|
||||
F70B9CB615E26A697D2CBEB4 = {isa = PBXGroup; children = (
|
||||
570EA8E9B2BD490DAA35F86E,
|
||||
C858CF44E96D416E4B6B9266,
|
||||
08EEB00E1779867598046EB6,
|
||||
FBCE051A0BA6C9FA3E64B47B, ); name = Frameworks; sourceTree = "<group>"; };
|
||||
40E8A594A7EAFA1EF5707952 = {isa = PBXGroup; children = (
|
||||
707149C59A1AF9752E428B97, ); name = Products; sourceTree = "<group>"; };
|
||||
5CB45B3816ED17D0620DDEBF = {isa = PBXGroup; children = (
|
||||
2B971235E85DF9D98B6FC8AF,
|
||||
0B35DCE65DF34DECBF1D8118,
|
||||
B24D9AE60E0CE5D1A75693B5,
|
||||
782C3BD0C802236A266FDEDD,
|
||||
F70B9CB615E26A697D2CBEB4,
|
||||
40E8A594A7EAFA1EF5707952, ); name = Source; sourceTree = "<group>"; };
|
||||
6FF8E864589AD3C2C06BF546 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"_DEBUG=1",
|
||||
"DEBUG=1",
|
||||
"JUCER_XCODE_MAC_F6D2F4CF=1",
|
||||
"JUCE_APP_VERSION=1.0.0",
|
||||
"JUCE_APP_VERSION_HEX=0x10000",
|
||||
"JucePlugin_Build_VST=0",
|
||||
"JucePlugin_Build_VST3=0",
|
||||
"JucePlugin_Build_AU=0",
|
||||
"JucePlugin_Build_AUv3=0",
|
||||
"JucePlugin_Build_RTAS=0",
|
||||
"JucePlugin_Build_AAX=0",
|
||||
"JucePlugin_Build_Standalone=0", );
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)");
|
||||
INFOPLIST_FILE = Info-App.plist;
|
||||
INFOPLIST_PREPROCESS = NO;
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.AnalyticsCollection;
|
||||
SDKROOT_ppc = macosx10.5;
|
||||
USE_HEADERMAP = NO; }; name = Debug; };
|
||||
8575FCD908F2B0E4E641C1A0 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 3;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"_NDEBUG=1",
|
||||
"NDEBUG=1",
|
||||
"JUCER_XCODE_MAC_F6D2F4CF=1",
|
||||
"JUCE_APP_VERSION=1.0.0",
|
||||
"JUCE_APP_VERSION_HEX=0x10000",
|
||||
"JucePlugin_Build_VST=0",
|
||||
"JucePlugin_Build_VST3=0",
|
||||
"JucePlugin_Build_AU=0",
|
||||
"JucePlugin_Build_AUv3=0",
|
||||
"JucePlugin_Build_RTAS=0",
|
||||
"JucePlugin_Build_AAX=0",
|
||||
"JucePlugin_Build_Standalone=0", );
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)");
|
||||
INFOPLIST_FILE = Info-App.plist;
|
||||
INFOPLIST_PREPROCESS = NO;
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.AnalyticsCollection;
|
||||
SDKROOT_ppc = macosx10.5;
|
||||
USE_HEADERMAP = NO; }; name = Release; };
|
||||
0399310F2F5034CFCB14437B = {isa = XCBuildConfiguration; buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||
GCC_WARN_MISSING_PARENTHESES = YES;
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "AnalyticsCollection";
|
||||
WARNING_CFLAGS = -Wreorder;
|
||||
ZERO_LINK = NO; }; name = Debug; };
|
||||
D9987A1AC287063A4E090185 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||
GCC_WARN_MISSING_PARENTHESES = YES;
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PRODUCT_NAME = "AnalyticsCollection";
|
||||
WARNING_CFLAGS = -Wreorder;
|
||||
ZERO_LINK = NO; }; name = Release; };
|
||||
E1B8C9CDDA25A31AA3C9C1BC = {isa = PBXTargetDependency; target = 3195ADB3A101AAE977C998D2; };
|
||||
65535D1056F6B2C9C545923E = {isa = XCConfigurationList; buildConfigurations = (
|
||||
0399310F2F5034CFCB14437B,
|
||||
D9987A1AC287063A4E090185, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
|
||||
850BB95DDE68E87344778037 = {isa = XCConfigurationList; buildConfigurations = (
|
||||
6FF8E864589AD3C2C06BF546,
|
||||
8575FCD908F2B0E4E641C1A0, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
|
||||
9DE971716CBA79E89467EFD0 = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
|
||||
A0DA914E3E16F49D60A5A47F, ); runOnlyForDeploymentPostprocessing = 0; };
|
||||
A01C1A7AFBB72E638096E0BA = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
|
||||
D293FC19C031441D146F2410,
|
||||
962036B1BB2EDB0F9D53E125,
|
||||
6297B7A712B1E5A74311F162,
|
||||
132F9FBC9EB36AF2E755325D,
|
||||
805CDCC5840B0D713C286826,
|
||||
C09B5A3CD0643CF37C9CF851,
|
||||
A1DF340E80EC501B1DBE75A0, ); runOnlyForDeploymentPostprocessing = 0; };
|
||||
32F46511CABBD859FD1D427D = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (
|
||||
B45E888BC48139CA81112E4A,
|
||||
375013DDDA026F2709E4FDAD,
|
||||
877F68400FB5A15B39719C61,
|
||||
38EE4929FFB8B83FB37B6E73, ); runOnlyForDeploymentPostprocessing = 0; };
|
||||
3195ADB3A101AAE977C998D2 = {isa = PBXNativeTarget; buildConfigurationList = 850BB95DDE68E87344778037; buildPhases = (
|
||||
9DE971716CBA79E89467EFD0,
|
||||
A01C1A7AFBB72E638096E0BA,
|
||||
32F46511CABBD859FD1D427D, ); buildRules = ( ); dependencies = ( ); name = "AnalyticsCollection - App"; productName = AnalyticsCollection; productReference = 707149C59A1AF9752E428B97; productType = "com.apple.product-type.application"; };
|
||||
8C6201B9CB81795542E3302D = {isa = PBXProject; buildConfigurationList = 65535D1056F6B2C9C545923E; attributes = { LastUpgradeCheck = 0830; TargetAttributes = { 3195ADB3A101AAE977C998D2 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 5CB45B3816ED17D0620DDEBF; projectDirPath = ""; projectRoot = ""; targets = (3195ADB3A101AAE977C998D2); };
|
||||
};
|
||||
rootObject = 8C6201B9CB81795542E3302D;
|
||||
}
|
||||
29
examples/AnalyticsCollection/Builds/MacOSX/Info-App.plist
Normal file
29
examples/AnalyticsCollection/Builds/MacOSX/Info-App.plist
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist>
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.yourcompany.AnalyticsCollection</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>AnalyticsCollection</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AnalyticsCollection</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.0</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
examples/AnalyticsCollection/Builds/MacOSX/RecentFilesMenuTemplate.nib
generated
Normal file
BIN
examples/AnalyticsCollection/Builds/MacOSX/RecentFilesMenuTemplate.nib
generated
Normal file
Binary file not shown.
|
|
@ -0,0 +1,20 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2017
|
||||
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnalyticsCollection - App", "AnalyticsCollection_App.vcxproj", "{C52D63D2-B7D8-F34E-1B84-186CB9D963EB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C52D63D2-B7D8-F34E-1B84-186CB9D963EB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C52D63D2-B7D8-F34E-1B84-186CB9D963EB}.Debug|x64.Build.0 = Debug|x64
|
||||
{C52D63D2-B7D8-F34E-1B84-186CB9D963EB}.Release|x64.ActiveCfg = Release|x64
|
||||
{C52D63D2-B7D8-F34E-1B84-186CB9D963EB}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,29 @@
|
|||
#ifdef JUCE_USER_DEFINED_RC_FILE
|
||||
#include JUCE_USER_DEFINED_RC_FILE
|
||||
#else
|
||||
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "AnalyticsCollection\0"
|
||||
VALUE "FileVersion", "1.0.0\0"
|
||||
VALUE "ProductName", "AnalyticsCollection\0"
|
||||
VALUE "ProductVersion", "1.0.0\0"
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
95AA57DF380DDDCD099D4000 = {isa = PBXBuildFile; fileRef = 707149C59A1AF9752E428B97; };
|
||||
F7E415084D290C237F9E638A = {isa = PBXBuildFile; fileRef = A93F5541F6B3C067538499EF; };
|
||||
A808E8D738B9BD079492797F = {isa = PBXBuildFile; fileRef = D87EBFBF8CF2D8160F22405B; };
|
||||
921F2D865DD5EBF5AA00DF38 = {isa = PBXBuildFile; fileRef = 644905C665C9F08A8700FE0D; };
|
||||
107547912F5D18FB3DD33009 = {isa = PBXBuildFile; fileRef = 192797C933B56812538409D4; };
|
||||
38EE4929FFB8B83FB37B6E73 = {isa = PBXBuildFile; fileRef = FBCE051A0BA6C9FA3E64B47B; };
|
||||
F6BB4E84E37BD38B6CA3025E = {isa = PBXBuildFile; fileRef = E206CE5D6771CAAA3C56F465; };
|
||||
02E32ED5F96146B51FE4669C = {isa = PBXBuildFile; fileRef = BC02966C48A4F51E9A187E4A; };
|
||||
D293FC19C031441D146F2410 = {isa = PBXBuildFile; fileRef = 6A86C9751E9DCFA62D4562DB; };
|
||||
962036B1BB2EDB0F9D53E125 = {isa = PBXBuildFile; fileRef = 33B9806EFA95DA05ACD9344E; };
|
||||
6297B7A712B1E5A74311F162 = {isa = PBXBuildFile; fileRef = 5DC0FF6BC4AE24FABC41F20E; };
|
||||
132F9FBC9EB36AF2E755325D = {isa = PBXBuildFile; fileRef = AD2CFF58DA5E1C6EDF9CC399; };
|
||||
805CDCC5840B0D713C286826 = {isa = PBXBuildFile; fileRef = A0DDFB3559C431E96EC59392; };
|
||||
C09B5A3CD0643CF37C9CF851 = {isa = PBXBuildFile; fileRef = 61FADB63565026F559F43F3B; };
|
||||
A1DF340E80EC501B1DBE75A0 = {isa = PBXBuildFile; fileRef = 65311EED96DCA9B62EBFEA04; };
|
||||
02589D465A73E0112B97BD3A = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
|
||||
192797C933B56812538409D4 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
1AA9DA887BE127DCED5228BB = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
|
||||
33B9806EFA95DA05ACD9344E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "include_juce_analytics.cpp"; path = "../../JuceLibraryCode/include_juce_analytics.cpp"; sourceTree = "SOURCE_ROOT"; };
|
||||
5219A3D3BECB8C7135C90377 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; path = "../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; };
|
||||
5DC0FF6BC4AE24FABC41F20E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_core.mm"; path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
61FADB63565026F559F43F3B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
644905C665C9F08A8700FE0D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
|
||||
65311EED96DCA9B62EBFEA04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_basics.mm"; path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
6A86C9751E9DCFA62D4562DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Main.cpp; path = ../../Source/Main.cpp; sourceTree = "SOURCE_ROOT"; };
|
||||
707149C59A1AF9752E428B97 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnalyticsCollection.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
|
||||
7A9FA859A2C2AE9FDDC99AD9 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; };
|
||||
886AEA380A40C905503764EB = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_graphics"; path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
|
||||
8A74F3F7422C89A897D93397 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
|
||||
8B927F72BA8726A064560942 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GoogleAnalyticsDestination.h; path = ../../Source/GoogleAnalyticsDestination.h; sourceTree = "SOURCE_ROOT"; };
|
||||
91208A06115D573563996967 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
|
||||
996BEF5ADCE2EC85EB9F637F = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_data_structures"; path = "../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
|
||||
A0DDFB3559C431E96EC59392 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_events.mm"; path = "../../JuceLibraryCode/include_juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
A93F5541F6B3C067538499EF = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
AD2CFF58DA5E1C6EDF9CC399 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
BC02966C48A4F51E9A187E4A = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = AnalyticsCollection/Images.xcassets; sourceTree = "SOURCE_ROOT"; };
|
||||
D352CDB4CA7E8B21FAA83B8C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainComponent.h; path = ../../Source/MainComponent.h; sourceTree = "SOURCE_ROOT"; };
|
||||
D87EBFBF8CF2D8160F22405B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; };
|
||||
E206CE5D6771CAAA3C56F465 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
F2CF007AA4C90AC7A5AD1604 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_analytics"; path = "../../../../modules/juce_analytics"; sourceTree = "SOURCE_ROOT"; };
|
||||
FBCE051A0BA6C9FA3E64B47B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
D269FA28B5D6012AEFE0BF20 = {isa = PBXGroup; children = (
|
||||
8B927F72BA8726A064560942,
|
||||
D352CDB4CA7E8B21FAA83B8C,
|
||||
6A86C9751E9DCFA62D4562DB, ); name = Source; sourceTree = "<group>"; };
|
||||
2B971235E85DF9D98B6FC8AF = {isa = PBXGroup; children = (
|
||||
D269FA28B5D6012AEFE0BF20, ); name = AnalyticsCollection; sourceTree = "<group>"; };
|
||||
0B35DCE65DF34DECBF1D8118 = {isa = PBXGroup; children = (
|
||||
F2CF007AA4C90AC7A5AD1604,
|
||||
02589D465A73E0112B97BD3A,
|
||||
996BEF5ADCE2EC85EB9F637F,
|
||||
1AA9DA887BE127DCED5228BB,
|
||||
886AEA380A40C905503764EB,
|
||||
5219A3D3BECB8C7135C90377, ); name = "Juce Modules"; sourceTree = "<group>"; };
|
||||
B24D9AE60E0CE5D1A75693B5 = {isa = PBXGroup; children = (
|
||||
8A74F3F7422C89A897D93397,
|
||||
33B9806EFA95DA05ACD9344E,
|
||||
5DC0FF6BC4AE24FABC41F20E,
|
||||
AD2CFF58DA5E1C6EDF9CC399,
|
||||
A0DDFB3559C431E96EC59392,
|
||||
61FADB63565026F559F43F3B,
|
||||
65311EED96DCA9B62EBFEA04,
|
||||
91208A06115D573563996967, ); name = "Juce Library Code"; sourceTree = "<group>"; };
|
||||
782C3BD0C802236A266FDEDD = {isa = PBXGroup; children = (
|
||||
7A9FA859A2C2AE9FDDC99AD9,
|
||||
BC02966C48A4F51E9A187E4A, ); name = Resources; sourceTree = "<group>"; };
|
||||
F70B9CB615E26A697D2CBEB4 = {isa = PBXGroup; children = (
|
||||
A93F5541F6B3C067538499EF,
|
||||
D87EBFBF8CF2D8160F22405B,
|
||||
644905C665C9F08A8700FE0D,
|
||||
192797C933B56812538409D4,
|
||||
FBCE051A0BA6C9FA3E64B47B,
|
||||
E206CE5D6771CAAA3C56F465, ); name = Frameworks; sourceTree = "<group>"; };
|
||||
40E8A594A7EAFA1EF5707952 = {isa = PBXGroup; children = (
|
||||
707149C59A1AF9752E428B97, ); name = Products; sourceTree = "<group>"; };
|
||||
5CB45B3816ED17D0620DDEBF = {isa = PBXGroup; children = (
|
||||
2B971235E85DF9D98B6FC8AF,
|
||||
0B35DCE65DF34DECBF1D8118,
|
||||
B24D9AE60E0CE5D1A75693B5,
|
||||
782C3BD0C802236A266FDEDD,
|
||||
F70B9CB615E26A697D2CBEB4,
|
||||
40E8A594A7EAFA1EF5707952, ); name = Source; sourceTree = "<group>"; };
|
||||
6FF8E864589AD3C2C06BF546 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"_DEBUG=1",
|
||||
"DEBUG=1",
|
||||
"JUCER_XCODE_IPHONE_5BC26AE3=1",
|
||||
"JUCE_APP_VERSION=1.0.0",
|
||||
"JUCE_APP_VERSION_HEX=0x10000",
|
||||
"JucePlugin_Build_VST=0",
|
||||
"JucePlugin_Build_VST3=0",
|
||||
"JucePlugin_Build_AU=0",
|
||||
"JucePlugin_Build_AUv3=0",
|
||||
"JucePlugin_Build_RTAS=0",
|
||||
"JucePlugin_Build_AAX=0",
|
||||
"JucePlugin_Build_Standalone=0", );
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)");
|
||||
INFOPLIST_FILE = Info-App.plist;
|
||||
INFOPLIST_PREPROCESS = NO;
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.AnalyticsCollection;
|
||||
USE_HEADERMAP = NO; }; name = Debug; };
|
||||
8575FCD908F2B0E4E641C1A0 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 3;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"_NDEBUG=1",
|
||||
"NDEBUG=1",
|
||||
"JUCER_XCODE_IPHONE_5BC26AE3=1",
|
||||
"JUCE_APP_VERSION=1.0.0",
|
||||
"JUCE_APP_VERSION_HEX=0x10000",
|
||||
"JucePlugin_Build_VST=0",
|
||||
"JucePlugin_Build_VST3=0",
|
||||
"JucePlugin_Build_AU=0",
|
||||
"JucePlugin_Build_AUv3=0",
|
||||
"JucePlugin_Build_RTAS=0",
|
||||
"JucePlugin_Build_AAX=0",
|
||||
"JucePlugin_Build_Standalone=0", );
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)");
|
||||
INFOPLIST_FILE = Info-App.plist;
|
||||
INFOPLIST_PREPROCESS = NO;
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.AnalyticsCollection;
|
||||
USE_HEADERMAP = NO; }; name = Release; };
|
||||
0399310F2F5034CFCB14437B = {isa = XCBuildConfiguration; buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||
GCC_WARN_MISSING_PARENTHESES = YES;
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "AnalyticsCollection";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
WARNING_CFLAGS = -Wreorder;
|
||||
ZERO_LINK = NO; }; name = Debug; };
|
||||
D9987A1AC287063A4E090185 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||
GCC_WARN_MISSING_PARENTHESES = YES;
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
|
||||
PRODUCT_NAME = "AnalyticsCollection";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
WARNING_CFLAGS = -Wreorder;
|
||||
ZERO_LINK = NO; }; name = Release; };
|
||||
E1B8C9CDDA25A31AA3C9C1BC = {isa = PBXTargetDependency; target = 3195ADB3A101AAE977C998D2; };
|
||||
65535D1056F6B2C9C545923E = {isa = XCConfigurationList; buildConfigurations = (
|
||||
0399310F2F5034CFCB14437B,
|
||||
D9987A1AC287063A4E090185, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
|
||||
850BB95DDE68E87344778037 = {isa = XCConfigurationList; buildConfigurations = (
|
||||
6FF8E864589AD3C2C06BF546,
|
||||
8575FCD908F2B0E4E641C1A0, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
|
||||
9DE971716CBA79E89467EFD0 = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
|
||||
02E32ED5F96146B51FE4669C, ); runOnlyForDeploymentPostprocessing = 0; };
|
||||
A01C1A7AFBB72E638096E0BA = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
|
||||
D293FC19C031441D146F2410,
|
||||
962036B1BB2EDB0F9D53E125,
|
||||
6297B7A712B1E5A74311F162,
|
||||
132F9FBC9EB36AF2E755325D,
|
||||
805CDCC5840B0D713C286826,
|
||||
C09B5A3CD0643CF37C9CF851,
|
||||
A1DF340E80EC501B1DBE75A0, ); runOnlyForDeploymentPostprocessing = 0; };
|
||||
32F46511CABBD859FD1D427D = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (
|
||||
F7E415084D290C237F9E638A,
|
||||
A808E8D738B9BD079492797F,
|
||||
921F2D865DD5EBF5AA00DF38,
|
||||
107547912F5D18FB3DD33009,
|
||||
38EE4929FFB8B83FB37B6E73,
|
||||
F6BB4E84E37BD38B6CA3025E, ); runOnlyForDeploymentPostprocessing = 0; };
|
||||
3195ADB3A101AAE977C998D2 = {isa = PBXNativeTarget; buildConfigurationList = 850BB95DDE68E87344778037; buildPhases = (
|
||||
9DE971716CBA79E89467EFD0,
|
||||
A01C1A7AFBB72E638096E0BA,
|
||||
32F46511CABBD859FD1D427D, ); buildRules = ( ); dependencies = ( ); name = "AnalyticsCollection - App"; productName = AnalyticsCollection; productReference = 707149C59A1AF9752E428B97; productType = "com.apple.product-type.application"; };
|
||||
8C6201B9CB81795542E3302D = {isa = PBXProject; buildConfigurationList = 65535D1056F6B2C9C545923E; attributes = { LastUpgradeCheck = 0830; TargetAttributes = { 3195ADB3A101AAE977C998D2 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 5CB45B3816ED17D0620DDEBF; projectDirPath = ""; projectRoot = ""; targets = (3195ADB3A101AAE977C998D2); };
|
||||
};
|
||||
rootObject = 8C6201B9CB81795542E3302D;
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
{
|
||||
"images": [
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "20x20",
|
||||
"filename": "Icon-Notification-20@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "20x20",
|
||||
"filename": "Icon-Notification-20@3x.png",
|
||||
"scale": "3x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "29x29",
|
||||
"filename": "Icon-29.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "29x29",
|
||||
"filename": "Icon-29@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "29x29",
|
||||
"filename": "Icon-29@3x.png",
|
||||
"scale": "3x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "40x40",
|
||||
"filename": "Icon-Spotlight-40@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "40x40",
|
||||
"filename": "Icon-Spotlight-40@3x.png",
|
||||
"scale": "3x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "57x57",
|
||||
"filename": "Icon.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "57x57",
|
||||
"filename": "Icon@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "60x60",
|
||||
"filename": "Icon-60@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "iphone",
|
||||
"size": "60x60",
|
||||
"filename": "Icon-@3x.png",
|
||||
"scale": "3x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "20x20",
|
||||
"filename": "Icon-Notifications-20.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "20x20",
|
||||
"filename": "Icon-Notifications-20@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "29x29",
|
||||
"filename": "Icon-Small-1.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "29x29",
|
||||
"filename": "Icon-Small@2x-1.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "40x40",
|
||||
"filename": "Icon-Spotlight-40.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "40x40",
|
||||
"filename": "Icon-Spotlight-40@2x-1.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "50x50",
|
||||
"filename": "Icon-Small-50.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "50x50",
|
||||
"filename": "Icon-Small-50@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "72x72",
|
||||
"filename": "Icon-72.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "72x72",
|
||||
"filename": "Icon-72@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "76x76",
|
||||
"filename": "Icon-76.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "76x76",
|
||||
"filename": "Icon-76@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "ipad",
|
||||
"size": "83.5x83.5",
|
||||
"filename": "Icon-83.5@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "ios-marketing",
|
||||
"size": "1024x1024",
|
||||
"filename": "Icon-AppStore-1024.png",
|
||||
"scale": "1x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"images": [
|
||||
{
|
||||
"orientation": "portrait",
|
||||
"idiom": "iphone",
|
||||
"extent": "full-screen",
|
||||
"minimum-system-version": "7.0",
|
||||
"scale": "2x",
|
||||
"filename": "LaunchImage-iphone-2x.png"
|
||||
},
|
||||
{
|
||||
"orientation": "portrait",
|
||||
"idiom": "iphone",
|
||||
"extent": "full-screen",
|
||||
"minimum-system-version": "7.0",
|
||||
"scale": "2x",
|
||||
"filename": "LaunchImage-iphone-retina4.png",
|
||||
"subtype": "retina4"
|
||||
},
|
||||
{
|
||||
"orientation": "portrait",
|
||||
"idiom": "ipad",
|
||||
"extent": "full-screen",
|
||||
"minimum-system-version": "7.0",
|
||||
"scale": "1x",
|
||||
"filename": "LaunchImage-ipad-portrait-1x.png"
|
||||
},
|
||||
{
|
||||
"orientation": "landscape",
|
||||
"idiom": "ipad",
|
||||
"extent": "full-screen",
|
||||
"minimum-system-version": "7.0",
|
||||
"scale": "1x",
|
||||
"filename": "LaunchImage-ipad-landscape-1x.png"
|
||||
},
|
||||
{
|
||||
"orientation": "portrait",
|
||||
"idiom": "ipad",
|
||||
"extent": "full-screen",
|
||||
"minimum-system-version": "7.0",
|
||||
"scale": "2x",
|
||||
"filename": "LaunchImage-ipad-portrait-2x.png"
|
||||
},
|
||||
{
|
||||
"orientation": "landscape",
|
||||
"idiom": "ipad",
|
||||
"extent": "full-screen",
|
||||
"minimum-system-version": "7.0",
|
||||
"scale": "2x",
|
||||
"filename": "LaunchImage-ipad-landscape-2x.png"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
43
examples/AnalyticsCollection/Builds/iOS/Info-App.plist
Normal file
43
examples/AnalyticsCollection/Builds/iOS/Info-App.plist
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist>
|
||||
<dict>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.yourcompany.AnalyticsCollection</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>AnalyticsCollection</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AnalyticsCollection</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.0</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
138
examples/AnalyticsCollection/JuceLibraryCode/AppConfig.h
Normal file
138
examples/AnalyticsCollection/JuceLibraryCode/AppConfig.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
There's a section below where you can add your own custom code safely, and the
|
||||
Projucer will preserve the contents of that block, but the best way to change
|
||||
any of these definitions is by using the Projucer's project settings.
|
||||
|
||||
Any commented-out settings will assume their default values.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//==============================================================================
|
||||
// [BEGIN_USER_CODE_SECTION]
|
||||
|
||||
// (You can add your own code in this section, and the Projucer will not overwrite it)
|
||||
|
||||
// [END_USER_CODE_SECTION]
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
In accordance with the terms of the JUCE 5 End-Use License Agreement, the
|
||||
JUCE Code in SECTION A cannot be removed, changed or otherwise rendered
|
||||
ineffective unless you have a JUCE Indie or Pro license, or are using JUCE
|
||||
under the GPL v3 license.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// BEGIN SECTION A
|
||||
|
||||
#ifndef JUCE_DISPLAY_SPLASH_SCREEN
|
||||
#define JUCE_DISPLAY_SPLASH_SCREEN 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_REPORT_APP_USAGE
|
||||
#define JUCE_REPORT_APP_USAGE 0
|
||||
#endif
|
||||
|
||||
|
||||
// END SECTION A
|
||||
|
||||
#define JUCE_USE_DARK_SPLASH_SCREEN 1
|
||||
|
||||
//==============================================================================
|
||||
#define JUCE_MODULE_AVAILABLE_juce_analytics 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_core 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_data_structures 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_events 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_graphics 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1
|
||||
|
||||
#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1
|
||||
|
||||
//==============================================================================
|
||||
// juce_core flags:
|
||||
|
||||
#ifndef JUCE_FORCE_DEBUG
|
||||
//#define JUCE_FORCE_DEBUG 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_LOG_ASSERTIONS
|
||||
//#define JUCE_LOG_ASSERTIONS 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_CHECK_MEMORY_LEAKS
|
||||
//#define JUCE_CHECK_MEMORY_LEAKS 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
||||
//#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_INCLUDE_ZLIB_CODE
|
||||
//#define JUCE_INCLUDE_ZLIB_CODE 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_CURL
|
||||
//#define JUCE_USE_CURL 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS
|
||||
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES
|
||||
//#define JUCE_ALLOW_STATIC_NULL_VARIABLES 1
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_events flags:
|
||||
|
||||
#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK
|
||||
//#define JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK 1
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_graphics flags:
|
||||
|
||||
#ifndef JUCE_USE_COREIMAGE_LOADER
|
||||
//#define JUCE_USE_COREIMAGE_LOADER 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_DIRECTWRITE
|
||||
//#define JUCE_USE_DIRECTWRITE 1
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_gui_basics flags:
|
||||
|
||||
#ifndef JUCE_ENABLE_REPAINT_DEBUGGING
|
||||
//#define JUCE_ENABLE_REPAINT_DEBUGGING 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_XSHM
|
||||
//#define JUCE_USE_XSHM 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_XRENDER
|
||||
//#define JUCE_USE_XRENDER 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_XCURSOR
|
||||
//#define JUCE_USE_XCURSOR 1
|
||||
#endif
|
||||
//==============================================================================
|
||||
#ifndef JUCE_STANDALONE_APPLICATION
|
||||
#if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone)
|
||||
#define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone
|
||||
#else
|
||||
#define JUCE_STANDALONE_APPLICATION 1
|
||||
#endif
|
||||
#endif
|
||||
38
examples/AnalyticsCollection/JuceLibraryCode/JuceHeader.h
Normal file
38
examples/AnalyticsCollection/JuceLibraryCode/JuceHeader.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
This is the header file that your files should include in order to get all the
|
||||
JUCE library headers. You should avoid including the JUCE headers directly in
|
||||
your own source files, because that wouldn't pick up the correct configuration
|
||||
options for your app.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AppConfig.h"
|
||||
|
||||
#include <juce_analytics/juce_analytics.h>
|
||||
#include <juce_core/juce_core.h>
|
||||
#include <juce_data_structures/juce_data_structures.h>
|
||||
#include <juce_events/juce_events.h>
|
||||
#include <juce_graphics/juce_graphics.h>
|
||||
#include <juce_gui_basics/juce_gui_basics.h>
|
||||
|
||||
|
||||
#if ! DONT_SET_USING_JUCE_NAMESPACE
|
||||
// If your code uses a lot of JUCE classes, then this will obviously save you
|
||||
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.
|
||||
using namespace juce;
|
||||
#endif
|
||||
|
||||
#if ! JUCE_DONT_DECLARE_PROJECTINFO
|
||||
namespace ProjectInfo
|
||||
{
|
||||
const char* const projectName = "AnalyticsCollection";
|
||||
const char* const versionString = "1.0.0";
|
||||
const int versionNumber = 0x10000;
|
||||
}
|
||||
#endif
|
||||
12
examples/AnalyticsCollection/JuceLibraryCode/ReadMe.txt
Normal file
12
examples/AnalyticsCollection/JuceLibraryCode/ReadMe.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
Important Note!!
|
||||
================
|
||||
|
||||
The purpose of this folder is to contain files that are auto-generated by the Projucer,
|
||||
and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
|
||||
the Projucer saves your project.
|
||||
|
||||
Therefore, it's a bad idea to make any manual changes to the files in here, or to
|
||||
put any of your own files in here if you don't want to lose them. (Of course you may choose
|
||||
to add the folder's contents to your version-control system so that you can re-merge your own
|
||||
modifications after the Projucer has saved its changes).
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_analytics/juce_analytics.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_core/juce_core.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_core/juce_core.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_data_structures/juce_data_structures.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_data_structures/juce_data_structures.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_events/juce_events.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_events/juce_events.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_graphics/juce_graphics.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_graphics/juce_graphics.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_gui_basics/juce_gui_basics.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_gui_basics/juce_gui_basics.mm>
|
||||
217
examples/AnalyticsCollection/Source/GoogleAnalyticsDestination.h
Normal file
217
examples/AnalyticsCollection/Source/GoogleAnalyticsDestination.h
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
|
||||
class GoogleAnalyticsDestination : public ThreadedAnalyticsDestination
|
||||
{
|
||||
public:
|
||||
GoogleAnalyticsDestination()
|
||||
: ThreadedAnalyticsDestination ("GoogleAnalyticsThread")
|
||||
{
|
||||
{
|
||||
// Choose where to save any unsent events.
|
||||
|
||||
auto appDataDir = File::getSpecialLocation (File::userApplicationDataDirectory)
|
||||
.getChildFile (JUCEApplication::getInstance()->getApplicationName());
|
||||
|
||||
if (! appDataDir.exists())
|
||||
appDataDir.createDirectory();
|
||||
|
||||
savedEventsFile = appDataDir.getChildFile ("analytics_events.xml");
|
||||
}
|
||||
|
||||
{
|
||||
// It's often a good idea to construct any analytics service API keys
|
||||
// at runtime, so they're not searchable in the binary distribution of
|
||||
// your application (but we've not done this here). You should replace
|
||||
// the following key with your own to get this example application
|
||||
// fully working.
|
||||
|
||||
apiKey = "UA-XXXXXXXXX-1";
|
||||
}
|
||||
|
||||
startAnalyticsThread (initialPeriodMs);
|
||||
}
|
||||
|
||||
~GoogleAnalyticsDestination()
|
||||
{
|
||||
// Here we sleep so that our background thread has a chance to send the
|
||||
// last lot of batched events. Be careful - if your app takes too long to
|
||||
// shut down then some operating systems will kill it forcibly!
|
||||
Thread::sleep (initialPeriodMs);
|
||||
|
||||
stopAnalyticsThread (1000);
|
||||
}
|
||||
|
||||
int getMaximumBatchSize() override { return 20; }
|
||||
|
||||
bool logBatchedEvents (const Array<AnalyticsEvent>& events) override
|
||||
{
|
||||
// Send events to Google Analytics.
|
||||
|
||||
String appData ("v=1&tid=" + apiKey + "&t=event&");
|
||||
|
||||
StringArray postData;
|
||||
|
||||
for (auto& event : events)
|
||||
{
|
||||
StringPairArray data;
|
||||
|
||||
if (event.name == "startup")
|
||||
{
|
||||
data.set ("ec", "info");
|
||||
data.set ("ea", "appStarted");
|
||||
}
|
||||
else if (event.name == "shutdown")
|
||||
{
|
||||
data.set ("ec", "info");
|
||||
data.set ("ea", "appStopped");
|
||||
}
|
||||
else if (event.name == "button_press")
|
||||
{
|
||||
data.set ("ec", "button_press");
|
||||
data.set ("ea", event.parameters["id"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
data.set ("cid", event.userID);
|
||||
|
||||
StringArray eventData;
|
||||
|
||||
for (auto& key : data.getAllKeys())
|
||||
eventData.add (key + "=" + URL::addEscapeChars (data[key], true));
|
||||
|
||||
postData.add (appData + eventData.joinIntoString ("&"));
|
||||
}
|
||||
|
||||
auto url = URL ("https://www.google-analytics.com/batch")
|
||||
.withPOSTData (postData.joinIntoString ("\n"));
|
||||
|
||||
{
|
||||
const ScopedLock lock (webStreamCreation);
|
||||
|
||||
if (shouldExit)
|
||||
return false;
|
||||
|
||||
webStream = new WebInputStream (url, true);
|
||||
}
|
||||
|
||||
const auto success = webStream->connect (nullptr);
|
||||
|
||||
// Do an exponential backoff if we failed to connect.
|
||||
if (success)
|
||||
periodMs = initialPeriodMs;
|
||||
else
|
||||
periodMs *= 2;
|
||||
|
||||
setBatchPeriod (periodMs);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void stopLoggingEvents() override
|
||||
{
|
||||
const ScopedLock lock (webStreamCreation);
|
||||
|
||||
shouldExit = true;
|
||||
|
||||
if (webStream != nullptr)
|
||||
webStream->cancel();
|
||||
}
|
||||
|
||||
private:
|
||||
void saveUnloggedEvents (const std::deque<AnalyticsEvent>& eventsToSave) override
|
||||
{
|
||||
// Save unsent events to disk. Here we use XML as a serialisation format, but
|
||||
// you can use anything else as long as the restoreUnloggedEvents method can
|
||||
// restore events from disk. If you're saving very large numbers of events then
|
||||
// a binary format may be more suitable if it is faster - remember that this
|
||||
// method is called on app shutdown so it needs to complete quickly!
|
||||
|
||||
XmlDocument previouslySavedEvents (savedEventsFile);
|
||||
ScopedPointer<XmlElement> xml = previouslySavedEvents.getDocumentElement();
|
||||
|
||||
if (xml == nullptr || xml->getTagName() != "events")
|
||||
xml = new XmlElement ("events");
|
||||
|
||||
for (auto& event : eventsToSave)
|
||||
{
|
||||
auto* xmlEvent = new XmlElement ("google_analytics_event");
|
||||
xmlEvent->setAttribute ("name", event.name);
|
||||
xmlEvent->setAttribute ("timestamp", (int) event.timestamp);
|
||||
xmlEvent->setAttribute ("user_id", event.userID);
|
||||
|
||||
auto* parameters = new XmlElement ("parameters");
|
||||
|
||||
for (auto& key : event.parameters.getAllKeys())
|
||||
parameters->setAttribute (key, event.parameters[key]);
|
||||
|
||||
xmlEvent->addChildElement (parameters);
|
||||
|
||||
auto* userProperties = new XmlElement ("user_properties");
|
||||
|
||||
for (auto& key : event.userProperties.getAllKeys())
|
||||
userProperties->setAttribute (key, event.userProperties[key]);
|
||||
|
||||
xmlEvent->addChildElement (userProperties);
|
||||
|
||||
xml->addChildElement (xmlEvent);
|
||||
}
|
||||
|
||||
xml->writeToFile (savedEventsFile, {});
|
||||
}
|
||||
|
||||
void restoreUnloggedEvents (std::deque<AnalyticsEvent>& restoredEventQueue) override
|
||||
{
|
||||
XmlDocument savedEvents (savedEventsFile);
|
||||
ScopedPointer<XmlElement> xml = savedEvents.getDocumentElement();
|
||||
|
||||
if (xml == nullptr || xml->getTagName() != "events")
|
||||
return;
|
||||
|
||||
const auto numEvents = xml->getNumChildElements();
|
||||
|
||||
for (auto iEvent = 0; iEvent < numEvents; ++iEvent)
|
||||
{
|
||||
const auto* xmlEvent = xml->getChildElement (iEvent);
|
||||
|
||||
StringPairArray parameters;
|
||||
const auto* xmlParameters = xmlEvent->getChildByName ("parameters");
|
||||
const auto numParameters = xmlParameters->getNumAttributes();
|
||||
|
||||
for (auto iParam = 0; iParam < numParameters; ++iParam)
|
||||
parameters.set (xmlParameters->getAttributeName (iParam),
|
||||
xmlParameters->getAttributeValue (iParam));
|
||||
|
||||
StringPairArray userProperties;
|
||||
const auto* xmlUserProperties = xmlEvent->getChildByName ("user_properties");
|
||||
const auto numUserProperties = xmlUserProperties->getNumAttributes();
|
||||
|
||||
for (auto iProp = 0; iProp < numUserProperties; ++iProp)
|
||||
userProperties.set (xmlUserProperties->getAttributeName (iProp),
|
||||
xmlUserProperties->getAttributeValue (iProp));
|
||||
|
||||
restoredEventQueue.push_back ({
|
||||
xmlEvent->getStringAttribute ("name"),
|
||||
(uint32) xmlEvent->getIntAttribute ("timestamp"),
|
||||
parameters,
|
||||
xmlEvent->getStringAttribute ("user_id"),
|
||||
userProperties
|
||||
});
|
||||
}
|
||||
|
||||
savedEventsFile.deleteFile();
|
||||
}
|
||||
|
||||
const int initialPeriodMs = 1000;
|
||||
int periodMs = initialPeriodMs;
|
||||
|
||||
CriticalSection webStreamCreation;
|
||||
bool shouldExit = false;
|
||||
ScopedPointer<WebInputStream> webStream;
|
||||
|
||||
String apiKey;
|
||||
|
||||
File savedEventsFile;
|
||||
};
|
||||
106
examples/AnalyticsCollection/Source/Main.cpp
Normal file
106
examples/AnalyticsCollection/Source/Main.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
|
||||
#include "GoogleAnalyticsDestination.h"
|
||||
#include "MainComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
class AnalyticsCollectionApplication : public JUCEApplication
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
AnalyticsCollectionApplication() {}
|
||||
|
||||
const String getApplicationName() override { return ProjectInfo::projectName; }
|
||||
const String getApplicationVersion() override { return ProjectInfo::versionString; }
|
||||
bool moreThanOneInstanceAllowed() override { return true; }
|
||||
|
||||
//==============================================================================
|
||||
void initialise (const String&) override
|
||||
{
|
||||
// Add an analytics identifier for the user. Make sure you don't collect
|
||||
// identifiable information accidentally if you haven't asked for permission!
|
||||
Analytics::getInstance()->setUserId ("AnonUser1234");
|
||||
|
||||
// Add any other constant user information.
|
||||
StringPairArray userData;
|
||||
userData.set ("group", "beta");
|
||||
Analytics::getInstance()->setUserProperties (userData);
|
||||
|
||||
// Add any analytics destinations we want to use to the Analytics singleton.
|
||||
Analytics::getInstance()->addDestination (new GoogleAnalyticsDestination());
|
||||
|
||||
Analytics::getInstance()->logEvent ("startup", {});
|
||||
|
||||
mainWindow = new MainWindow (getApplicationName());
|
||||
}
|
||||
|
||||
void shutdown() override
|
||||
{
|
||||
Analytics::getInstance()->logEvent ("shutdown", {});
|
||||
|
||||
// Add your application's shutdown code here..
|
||||
|
||||
mainWindow = nullptr; // (deletes our window)
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void systemRequestedQuit() override
|
||||
{
|
||||
// This is called when the app is being asked to quit: you can ignore this
|
||||
// request and let the app carry on running, or call quit() to allow the app to close.
|
||||
quit();
|
||||
}
|
||||
|
||||
void anotherInstanceStarted (const String&) override
|
||||
{
|
||||
// When another instance of the app is launched while this one is running,
|
||||
// this method is invoked, and the commandLine parameter tells you what
|
||||
// the other instance's command-line arguments were.
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This class implements the desktop window that contains an instance of
|
||||
our MainContentComponent class.
|
||||
*/
|
||||
class MainWindow : public DocumentWindow
|
||||
{
|
||||
public:
|
||||
MainWindow (String name) : DocumentWindow (name,
|
||||
Desktop::getInstance().getDefaultLookAndFeel()
|
||||
.findColour (ResizableWindow::backgroundColourId),
|
||||
DocumentWindow::allButtons)
|
||||
{
|
||||
setUsingNativeTitleBar (true);
|
||||
setContentOwned (new MainContentComponent(), true);
|
||||
|
||||
centreWithSize (getWidth(), getHeight());
|
||||
setVisible (true);
|
||||
}
|
||||
|
||||
void closeButtonPressed() override
|
||||
{
|
||||
// This is called when the user tries to close this window. Here, we'll just
|
||||
// ask the app to quit when this happens, but you can change this to do
|
||||
// whatever you need.
|
||||
JUCEApplication::getInstance()->systemRequestedQuit();
|
||||
}
|
||||
|
||||
/* Note: Be careful if you override any DocumentWindow methods - the base
|
||||
class uses a lot of them, so by overriding you might break its functionality.
|
||||
It's best to do all your work in your content component instead, but if
|
||||
you really have to override any DocumentWindow methods, make sure your
|
||||
subclass also calls the superclass's method.
|
||||
*/
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
|
||||
};
|
||||
|
||||
private:
|
||||
ScopedPointer<MainWindow> mainWindow;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// This macro generates the main() routine that launches the app.
|
||||
START_JUCE_APPLICATION (AnalyticsCollectionApplication)
|
||||
38
examples/AnalyticsCollection/Source/MainComponent.h
Normal file
38
examples/AnalyticsCollection/Source/MainComponent.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
|
||||
class MainContentComponent : public Component
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
MainContentComponent()
|
||||
{
|
||||
addAndMakeVisible (eventButton);
|
||||
|
||||
setSize (300, 200);
|
||||
|
||||
StringPairArray logButtonPressParameters;
|
||||
logButtonPressParameters.set ("id", "a");
|
||||
logEventButtonPress = new ButtonTracker (eventButton, "button_press", logButtonPressParameters);
|
||||
}
|
||||
|
||||
~MainContentComponent() {}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
eventButton.centreWithSize (100, 50);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
TextButton eventButton { "Press me!" };
|
||||
ScopedPointer<ButtonTracker> logEventButtonPress;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
|
||||
};
|
||||
|
|
@ -39,6 +39,7 @@
|
|||
<MODULEPATH id="juce_audio_utils" path="../../modules"/>
|
||||
<MODULEPATH id="juce_blocks_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_product_unlocking" path="../../modules"/>
|
||||
<MODULEPATH id="juce_analytics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</XCODE_MAC>
|
||||
<LINUX_MAKE targetFolder="Builds/LinuxMakefile">
|
||||
|
|
@ -67,6 +68,7 @@
|
|||
<MODULEPATH id="juce_audio_utils" path="../../modules"/>
|
||||
<MODULEPATH id="juce_blocks_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_product_unlocking" path="../../modules"/>
|
||||
<MODULEPATH id="juce_analytics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</LINUX_MAKE>
|
||||
<VS2017 targetFolder="Builds/VisualStudio2017">
|
||||
|
|
@ -97,10 +99,12 @@
|
|||
<MODULEPATH id="juce_audio_formats" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_devices" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_analytics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</VS2017>
|
||||
</EXPORTFORMATS>
|
||||
<MODULES>
|
||||
<MODULE id="juce_analytics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
|
||||
<MODULES id="juce_audio_basics" showAllCode="1" useLocalCopy="0"/>
|
||||
<MODULES id="juce_audio_devices" showAllCode="1" useLocalCopy="0"/>
|
||||
<MODULES id="juce_audio_formats" showAllCode="1" useLocalCopy="0"/>
|
||||
|
|
|
|||
67
modules/juce_analytics/analytics/juce_Analytics.cpp
Normal file
67
modules/juce_analytics/analytics/juce_Analytics.cpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
void Analytics::addDestination (AnalyticsDestination* destination)
|
||||
{
|
||||
destinations.add (destination);
|
||||
}
|
||||
|
||||
void Analytics::setUserId (const String& newUserId)
|
||||
{
|
||||
userId = newUserId;
|
||||
}
|
||||
|
||||
void Analytics::setUserProperties (const StringPairArray& properties)
|
||||
{
|
||||
userProperties = properties;
|
||||
}
|
||||
|
||||
void Analytics::logEvent (const String& eventName,
|
||||
const StringPairArray& parameters)
|
||||
{
|
||||
if (! isSuspended)
|
||||
{
|
||||
AnalyticsDestination::AnalyticsEvent event
|
||||
{
|
||||
eventName,
|
||||
Time::getMillisecondCounter(),
|
||||
parameters,
|
||||
userId,
|
||||
userProperties
|
||||
};
|
||||
|
||||
for (auto* destination : destinations)
|
||||
destination->logEvent (event);
|
||||
}
|
||||
}
|
||||
|
||||
void Analytics::setSuspended (bool shouldBeSuspended)
|
||||
{
|
||||
isSuspended = shouldBeSuspended;
|
||||
}
|
||||
|
||||
juce_ImplementSingleton (Analytics)
|
||||
|
||||
}
|
||||
99
modules/juce_analytics/analytics/juce_Analytics.h
Normal file
99
modules/juce_analytics/analytics/juce_Analytics.h
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A singleton class to manage analytics data.
|
||||
|
||||
Use an Analytics object to manage sending analytics data to one or more
|
||||
AnalyticsDestinations.
|
||||
|
||||
@see AnalyticsDestination, ThreadedAnalyticsDestination,
|
||||
AnalyticsDestination::AnalyticsEvent
|
||||
*/
|
||||
class JUCE_API Analytics : public DeletedAtShutdown
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Adds an AnalyticsDestination to the list of AnalyticsDestinations
|
||||
managed by this Analytics object.
|
||||
|
||||
The Analytics class will take ownership of the AnalyticsDestination
|
||||
passed to this function.
|
||||
|
||||
@param destination the AnalyticsDestination to manage
|
||||
*/
|
||||
void addDestination (AnalyticsDestination* destination);
|
||||
|
||||
/** Sets a user ID that will be added to all AnalyticsEvents sent to
|
||||
AnalyticsDestinations.
|
||||
|
||||
@param newUserId the userId to add to AnalyticsEvents
|
||||
*/
|
||||
void setUserId (const String& newUserId);
|
||||
|
||||
/** Sets some user properties that will be added to all AnalyticsEvents sent
|
||||
to AnalyticsDestinations.
|
||||
|
||||
@param properties the userProperties to add to AnalyticsEvents
|
||||
*/
|
||||
void setUserProperties (const StringPairArray& properties);
|
||||
|
||||
/** Sends an AnalyticsEvent to all AnalyticsDestinations.
|
||||
|
||||
The AnalyticsEvent will be timestamped, and will have the userId and
|
||||
userProperties populated by values previously set by calls to
|
||||
setUserId and setUserProperties. The name and parameters will be
|
||||
populated by the arguments supplied to this function.
|
||||
|
||||
@param eventName the event name
|
||||
@param parameters the event parameters
|
||||
*/
|
||||
void logEvent (const String& eventName, const StringPairArray& parameters);
|
||||
|
||||
/** Suspends analytics submission to AnalyticsDestinations.
|
||||
|
||||
@param shouldBeSuspended if event submission should be suspended
|
||||
*/
|
||||
void setSuspended (bool shouldBeSuspended);
|
||||
|
||||
|
||||
juce_DeclareSingleton (Analytics, true)
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Analytics() = default;
|
||||
|
||||
String userId;
|
||||
StringPairArray userProperties;
|
||||
|
||||
bool isSuspended = false;
|
||||
|
||||
OwnedArray<AnalyticsDestination> destinations;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Analytics)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
55
modules/juce_analytics/analytics/juce_ButtonTracker.cpp
Normal file
55
modules/juce_analytics/analytics/juce_ButtonTracker.cpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ButtonTracker::ButtonTracker (Button& buttonToTrack,
|
||||
const String& triggeredEventName,
|
||||
const StringPairArray& triggeredEventParameters)
|
||||
: button (buttonToTrack),
|
||||
eventName (triggeredEventName),
|
||||
eventParameters (triggeredEventParameters)
|
||||
{
|
||||
button.addListener (this);
|
||||
}
|
||||
|
||||
ButtonTracker::~ButtonTracker()
|
||||
{
|
||||
button.removeListener (this);
|
||||
}
|
||||
|
||||
void ButtonTracker::buttonClicked (Button* b)
|
||||
{
|
||||
if (b == &button)
|
||||
{
|
||||
auto params = eventParameters;
|
||||
|
||||
if (button.getClickingTogglesState())
|
||||
params.set ("ButtonState", button.getToggleState() ? "On" : "Off");
|
||||
|
||||
Analytics::getInstance()->logEvent (eventName, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace juce
|
||||
70
modules/juce_analytics/analytics/juce_ButtonTracker.h
Normal file
70
modules/juce_analytics/analytics/juce_ButtonTracker.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class that automatically sends analytics events to the Analytics singleton
|
||||
when a button is clicked.
|
||||
|
||||
@see Analytics, AnalyticsDestination::AnalyticsEvent
|
||||
*/
|
||||
class JUCE_API ButtonTracker : private Button::Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/**
|
||||
Creating one of these automatically sends analytics events to the Analytics
|
||||
singeton when the corresponding button is clicked.
|
||||
|
||||
The name and parameters of the analytics event will be populated from the
|
||||
variables supplied here. If clicking changes the button's state then the
|
||||
parameters will have a {"ButtonState", "On"/"Off"} entry added.
|
||||
|
||||
@param buttonToTrack the button to track
|
||||
@param triggeredEventName the name of the generated event
|
||||
@param triggeredEventParameters the parameters to add to the generated
|
||||
event
|
||||
|
||||
@see Analytics, AnalyticsDestination::AnalyticsEvent
|
||||
*/
|
||||
ButtonTracker (Button& buttonToTrack,
|
||||
const String& triggeredEventName,
|
||||
const StringPairArray& triggeredEventParameters = {});
|
||||
|
||||
/** Destructor. */
|
||||
~ButtonTracker();
|
||||
|
||||
private:
|
||||
/** @internal */
|
||||
void buttonClicked (Button*) override;
|
||||
|
||||
Button& button;
|
||||
const String eventName;
|
||||
const StringPairArray eventParameters;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonTracker)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An interface for handling analytics events collected by an Analytics object.
|
||||
|
||||
For basic analytics logging you can implement this interface and add your
|
||||
class to an Analytics object.
|
||||
|
||||
For more advanced logging you may want to subclass
|
||||
ThreadedAnalyticsDestination instead, which is more suitable for interacting
|
||||
with web servers and other time consuming destinations.
|
||||
|
||||
@see Analytics, ThreadedAnalyticsDestination
|
||||
*/
|
||||
struct JUCE_API AnalyticsDestination
|
||||
{
|
||||
/** Contains information about an event to be logged. */
|
||||
struct AnalyticsEvent
|
||||
{
|
||||
/** The name of the event. */
|
||||
String name;
|
||||
|
||||
/**
|
||||
The timestamp of the event.
|
||||
|
||||
Timestamps are automatically applied by an Analytics object and are
|
||||
derived from Time::getMillisecondCounter(). As such these timestamps
|
||||
do not represent absolute times, but relative timings of events for
|
||||
each user in each session will be accurate.
|
||||
*/
|
||||
uint32 timestamp;
|
||||
|
||||
/** The parameters of the event. */
|
||||
StringPairArray parameters;
|
||||
|
||||
/** The user ID associated with the event. */
|
||||
String userID;
|
||||
|
||||
/** Properties associated with the user. */
|
||||
StringPairArray userProperties;
|
||||
};
|
||||
|
||||
/** Constructor. */
|
||||
AnalyticsDestination() = default;
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~AnalyticsDestination() {}
|
||||
|
||||
/**
|
||||
When an AnalyticsDestination is added to an Analytics object this method
|
||||
is called when an analytics event is triggered from the Analytics
|
||||
object.
|
||||
|
||||
Override this method to log the event information somewhere useful.
|
||||
*/
|
||||
virtual void logEvent (const AnalyticsEvent& event) = 0;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnalyticsDestination)
|
||||
};
|
||||
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ThreadedAnalyticsDestination::ThreadedAnalyticsDestination (const String& threadName)
|
||||
: dispatcher (threadName, *this)
|
||||
{}
|
||||
|
||||
ThreadedAnalyticsDestination::~ThreadedAnalyticsDestination()
|
||||
{
|
||||
// If you hit this assertion then the analytics thread has not been shut down
|
||||
// before this class is destroyed. Call stopAnalyticsThread() in your destructor!
|
||||
jassert (! dispatcher.isThreadRunning());
|
||||
}
|
||||
|
||||
void ThreadedAnalyticsDestination::setBatchPeriod (int newBatchPeriodMilliseconds)
|
||||
{
|
||||
dispatcher.batchPeriodMilliseconds = newBatchPeriodMilliseconds;
|
||||
}
|
||||
|
||||
void ThreadedAnalyticsDestination::logEvent (const AnalyticsEvent& event)
|
||||
{
|
||||
dispatcher.addToQueue (event);
|
||||
}
|
||||
|
||||
void ThreadedAnalyticsDestination::startAnalyticsThread (int initialBatchPeriodMilliseconds)
|
||||
{
|
||||
setBatchPeriod (initialBatchPeriodMilliseconds);
|
||||
dispatcher.startThread();
|
||||
}
|
||||
|
||||
void ThreadedAnalyticsDestination::stopAnalyticsThread (int timeout)
|
||||
{
|
||||
dispatcher.signalThreadShouldExit();
|
||||
stopLoggingEvents();
|
||||
dispatcher.stopThread (timeout);
|
||||
|
||||
if (dispatcher.eventQueue.size() > 0)
|
||||
saveUnloggedEvents (dispatcher.eventQueue);
|
||||
}
|
||||
|
||||
ThreadedAnalyticsDestination::EventDispatcher::EventDispatcher (const String& threadName,
|
||||
ThreadedAnalyticsDestination& destination)
|
||||
: Thread (threadName),
|
||||
parent (destination)
|
||||
{}
|
||||
|
||||
void ThreadedAnalyticsDestination::EventDispatcher::run()
|
||||
{
|
||||
// We may have inserted some events into the queue (on the message thread)
|
||||
// before this thread has started, so make sure the old events are at the
|
||||
// front of the queue.
|
||||
{
|
||||
std::deque<AnalyticsEvent> restoredEventQueue;
|
||||
parent.restoreUnloggedEvents (restoredEventQueue);
|
||||
|
||||
const ScopedLock lock (queueAccess);
|
||||
|
||||
for (auto rit = restoredEventQueue.rbegin(); rit != restoredEventQueue.rend(); ++rit)
|
||||
eventQueue.push_front (*rit);
|
||||
}
|
||||
|
||||
const int maxBatchSize = parent.getMaximumBatchSize();
|
||||
|
||||
while (! threadShouldExit())
|
||||
{
|
||||
auto eventsToSendCapacity = maxBatchSize - eventsToSend.size();
|
||||
|
||||
if (eventsToSendCapacity > 0)
|
||||
{
|
||||
const ScopedLock lock (queueAccess);
|
||||
|
||||
const auto numEventsInQueue = (int) eventQueue.size();
|
||||
|
||||
if (numEventsInQueue > 0)
|
||||
{
|
||||
const auto numEventsToAdd = jmin (eventsToSendCapacity, numEventsInQueue);
|
||||
|
||||
for (size_t i = 0; i < (size_t) numEventsToAdd; ++i)
|
||||
eventsToSend.add (eventQueue[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const auto submissionTime = Time::getMillisecondCounter();
|
||||
|
||||
if (! eventsToSend.isEmpty())
|
||||
{
|
||||
if (parent.logBatchedEvents (eventsToSend))
|
||||
{
|
||||
const ScopedLock lock (queueAccess);
|
||||
|
||||
for (auto i = 0; i < eventsToSend.size(); ++i)
|
||||
eventQueue.pop_front();
|
||||
|
||||
eventsToSend.clearQuick();
|
||||
}
|
||||
}
|
||||
|
||||
while (Time::getMillisecondCounter() - submissionTime < (uint32) batchPeriodMilliseconds.get())
|
||||
{
|
||||
if (threadShouldExit())
|
||||
return;
|
||||
|
||||
Thread::sleep (100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadedAnalyticsDestination::EventDispatcher::addToQueue (const AnalyticsEvent& event)
|
||||
{
|
||||
const ScopedLock lock (queueAccess);
|
||||
eventQueue.push_back (event);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
namespace DestinationTestHelpers
|
||||
{
|
||||
//==============================================================================
|
||||
struct TestDestination : public ThreadedAnalyticsDestination
|
||||
{
|
||||
TestDestination (std::deque<AnalyticsEvent>& loggedEvents,
|
||||
std::deque<AnalyticsEvent>& unloggedEvents)
|
||||
: ThreadedAnalyticsDestination ("ThreadedAnalyticsDestinationTest"),
|
||||
loggedEventQueue (loggedEvents),
|
||||
unloggedEventStore (unloggedEvents)
|
||||
{}
|
||||
|
||||
virtual ~TestDestination() {}
|
||||
|
||||
int getMaximumBatchSize() override
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
void saveUnloggedEvents (const std::deque<AnalyticsEvent>& eventsToSave) override
|
||||
{
|
||||
unloggedEventStore = eventsToSave;
|
||||
}
|
||||
|
||||
void restoreUnloggedEvents (std::deque<AnalyticsEvent>& restoredEventQueue) override
|
||||
{
|
||||
restoredEventQueue = unloggedEventStore;
|
||||
}
|
||||
|
||||
std::deque<AnalyticsEvent>& loggedEventQueue;
|
||||
std::deque<AnalyticsEvent>& unloggedEventStore;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct BasicDestination : public TestDestination
|
||||
{
|
||||
BasicDestination (std::deque<AnalyticsEvent>& loggedEvents,
|
||||
std::deque<AnalyticsEvent>& unloggedEvents)
|
||||
: TestDestination (loggedEvents, unloggedEvents)
|
||||
{
|
||||
startAnalyticsThread (100);
|
||||
}
|
||||
|
||||
virtual ~BasicDestination()
|
||||
{
|
||||
stopAnalyticsThread (1000);
|
||||
}
|
||||
|
||||
|
||||
bool logBatchedEvents (const Array<AnalyticsEvent>& events) override
|
||||
{
|
||||
jassert (events.size() <= getMaximumBatchSize());
|
||||
|
||||
for (auto& event : events)
|
||||
loggedEventQueue.push_back (event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void stopLoggingEvents() override {}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct SlowWebDestination : public TestDestination
|
||||
{
|
||||
SlowWebDestination (std::deque<AnalyticsEvent>& loggedEvents,
|
||||
std::deque<AnalyticsEvent>& unloggedEvents)
|
||||
: TestDestination (loggedEvents, unloggedEvents)
|
||||
{
|
||||
startAnalyticsThread (initialPeriod);
|
||||
}
|
||||
|
||||
virtual ~SlowWebDestination()
|
||||
{
|
||||
stopAnalyticsThread (1000);
|
||||
}
|
||||
|
||||
bool logBatchedEvents (const Array<AnalyticsEvent>& events) override
|
||||
{
|
||||
threadHasStarted.signal();
|
||||
|
||||
jassert (events.size() <= getMaximumBatchSize());
|
||||
|
||||
{
|
||||
const ScopedLock lock (webStreamCreation);
|
||||
|
||||
if (shouldExit)
|
||||
return false;
|
||||
|
||||
// An attempt to connect to an unroutable IP address will hang
|
||||
// indefinitely, which simulates a very slow server
|
||||
webStream = new WebInputStream (URL ("http://1.192.0.0"), true);
|
||||
}
|
||||
|
||||
String data;
|
||||
|
||||
for (auto& event : events)
|
||||
data << event.name;
|
||||
|
||||
webStream->withExtraHeaders (data);
|
||||
|
||||
const auto success = webStream->connect (nullptr);
|
||||
|
||||
// Exponential backoff on failure
|
||||
if (success)
|
||||
period = initialPeriod;
|
||||
else
|
||||
period *= 2;
|
||||
|
||||
setBatchPeriod (period);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void stopLoggingEvents() override
|
||||
{
|
||||
const ScopedLock lock (webStreamCreation);
|
||||
|
||||
shouldExit = true;
|
||||
|
||||
if (webStream != nullptr)
|
||||
webStream->cancel();
|
||||
}
|
||||
|
||||
const int initialPeriod = 100;
|
||||
int period = initialPeriod;
|
||||
|
||||
CriticalSection webStreamCreation;
|
||||
bool shouldExit = false;
|
||||
|
||||
ScopedPointer<WebInputStream> webStream;
|
||||
|
||||
WaitableEvent threadHasStarted;
|
||||
};
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct ThreadedAnalyticsDestinationTests : public UnitTest
|
||||
{
|
||||
ThreadedAnalyticsDestinationTests()
|
||||
: UnitTest ("ThreadedAnalyticsDestination")
|
||||
{}
|
||||
|
||||
void compareEventQueues (const std::deque<AnalyticsDestination::AnalyticsEvent>& a,
|
||||
const std::deque<AnalyticsDestination::AnalyticsEvent>& b)
|
||||
{
|
||||
const auto numEntries = a.size();
|
||||
expectEquals (b.size(), numEntries);
|
||||
|
||||
for (size_t i = 0; i < numEntries; ++i)
|
||||
{
|
||||
expectEquals (a[i].name, b[i].name);
|
||||
expect (a[i].timestamp == b[i].timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
std::deque<AnalyticsDestination::AnalyticsEvent> testEvents;
|
||||
|
||||
for (int i = 0; i < 7; ++i)
|
||||
testEvents.push_back ({ String (i), Time::getMillisecondCounter(), {}, "TestUser", {} });
|
||||
|
||||
std::deque<AnalyticsDestination::AnalyticsEvent> loggedEvents, unloggedEvents;
|
||||
|
||||
beginTest ("Basic");
|
||||
{
|
||||
DestinationTestHelpers::BasicDestination destination (loggedEvents, unloggedEvents);
|
||||
|
||||
for (auto& event : testEvents)
|
||||
destination.logEvent (event);
|
||||
|
||||
Thread::sleep (400);
|
||||
|
||||
compareEventQueues (loggedEvents, testEvents);
|
||||
expect (unloggedEvents.size() == 0);
|
||||
|
||||
loggedEvents.clear();
|
||||
}
|
||||
|
||||
beginTest ("Web");
|
||||
{
|
||||
{
|
||||
DestinationTestHelpers::SlowWebDestination destination (loggedEvents, unloggedEvents);
|
||||
|
||||
for (auto& event : testEvents)
|
||||
destination.logEvent (event);
|
||||
}
|
||||
|
||||
expect (loggedEvents.size() == 0);
|
||||
compareEventQueues (unloggedEvents, testEvents);
|
||||
|
||||
{
|
||||
DestinationTestHelpers::SlowWebDestination destination (loggedEvents, unloggedEvents);
|
||||
|
||||
destination.threadHasStarted.wait();
|
||||
unloggedEvents.clear();
|
||||
}
|
||||
|
||||
expect (loggedEvents.size() == 0);
|
||||
compareEventQueues (unloggedEvents, testEvents);
|
||||
|
||||
unloggedEvents.clear();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static ThreadedAnalyticsDestinationTests threadedAnalyticsDestinationTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A base class for dispatching analytics events on a dedicated thread.
|
||||
|
||||
This class is particularly useful for sending analytics events to a web
|
||||
server without blocking the message thread. It can also save (and restore)
|
||||
events that were not dispatched so no information is lost when an internet
|
||||
connection is absent or something else prevents successful logging.
|
||||
|
||||
Once startAnalyticsThread is called the logBatchedEvents method is
|
||||
periodically invoked on an analytics thread, with the period determined by
|
||||
calls to setBatchPeriod. Here events are grouped together into batches, with
|
||||
the maximum batch size set by the implementation of getMaximumBatchSize.
|
||||
|
||||
It's important to call stopAnalyticsThread in the destructor of your
|
||||
subclass (or before then) to give the analytics thread time to shut down.
|
||||
Calling stopAnalyticsThread will, in turn, call stopLoggingEvents, which
|
||||
you should use to terminate the currently running logBatchedEvents call.
|
||||
|
||||
@see Analytics, AnalyticsDestination, AnalyticsDestination::AnalyticsEvent
|
||||
*/
|
||||
class JUCE_API ThreadedAnalyticsDestination : public AnalyticsDestination
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/**
|
||||
Creates a ThreadedAnalyticsDestination.
|
||||
|
||||
@param threadName used to identify the analytics
|
||||
thread in debug builds
|
||||
*/
|
||||
ThreadedAnalyticsDestination (const String& threadName = "Analytics thread");
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~ThreadedAnalyticsDestination();
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Override this method to provide the maximum batch size you can handle in
|
||||
your subclass.
|
||||
|
||||
Calls to logBatchedEvents will contain no more than this number of events.
|
||||
*/
|
||||
virtual int getMaximumBatchSize() = 0;
|
||||
|
||||
/**
|
||||
This method will be called periodically on the analytics thread.
|
||||
|
||||
If this method returns false then the subsequent call of this function will
|
||||
contain the same events as previous call, plus any new events that have been
|
||||
generated in the period between calls. The order of events will not be
|
||||
changed. This allows you to retry logging events until they are logged
|
||||
successfully.
|
||||
|
||||
@param events a list of events to be logged
|
||||
@returns if the events were successfully logged
|
||||
*/
|
||||
virtual bool logBatchedEvents (const Array<AnalyticsEvent>& events) = 0;
|
||||
|
||||
/**
|
||||
You must always call stopAnalyticsThread in the destructor of your subclass
|
||||
(or before then) to give the analytics thread time to shut down.
|
||||
|
||||
Calling stopAnalyticsThread triggers a call to this method. At this point
|
||||
you are guaranteed that logBatchedEvents has been called for the last time
|
||||
and you should make sure that the current call to logBatchedEvents finishes
|
||||
as quickly as possible. This method and a subsequent call to
|
||||
saveUnloggedEvents must both complete before the timeout supplied to
|
||||
stopAnalyticsThread.
|
||||
|
||||
In a normal use case stopLoggingEvents will be called on the message thread
|
||||
from the destructor of your ThreadedAnalyticsDestination subclass, and must
|
||||
stop the logBatchedEvents method which is running on the analytics thread.
|
||||
|
||||
@see stopAnalyticsThread
|
||||
*/
|
||||
virtual void stopLoggingEvents() = 0;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Call this to set the period between logBatchedEvents invocations.
|
||||
|
||||
This method is thread safe and can be used to implements things like
|
||||
exponential backoff in logBatchedEvents calls.
|
||||
|
||||
@param newSubmissionPeriodMilliseconds the new submission period to
|
||||
use in milliseconds
|
||||
*/
|
||||
void setBatchPeriod (int newSubmissionPeriodMilliseconds);
|
||||
|
||||
/**
|
||||
Adds an event to the queue, which will ultimately be submitted to
|
||||
logBatchedEvents.
|
||||
|
||||
This method is thread safe.
|
||||
|
||||
@param event the analytics event to add to the queue
|
||||
*/
|
||||
void logEvent (const AnalyticsEvent& event) override final;
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/**
|
||||
Starts the analytics thread, with an initial event batching period.
|
||||
|
||||
@param initialBatchPeriodMilliseconds the initial event batching period
|
||||
in milliseconds
|
||||
*/
|
||||
void startAnalyticsThread (int initialBatchPeriodMilliseconds);
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Triggers the shutdown of the analytics thread.
|
||||
|
||||
You must call this method in the destructor of your subclass (or before
|
||||
then) to give the analytics thread time to shut down.
|
||||
|
||||
This method invokes stopLoggingEvents and you should ensure that both the
|
||||
analytics thread and a call to saveUnloggedEvents are able to finish before
|
||||
the supplied timeout. This timeout is important because on platforms like
|
||||
iOS an app is killed if it takes too long to shut down.
|
||||
|
||||
@param timeoutMilliseconds the number of milliseconds before
|
||||
the analytics thread is forcibly
|
||||
terminated
|
||||
*/
|
||||
void stopAnalyticsThread (int timeoutMilliseconds);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
/**
|
||||
This method will be called when the analytics thread is shut down,
|
||||
giving you the chance to save any analytics events that could not be
|
||||
logged. Once saved these events can be put back into the queue of events
|
||||
when the ThreadedAnalyticsDestination is recreated via
|
||||
restoreUnloggedEvents.
|
||||
|
||||
This method should return as quickly as possible, as both
|
||||
stopLoggingEvents and this method need to complete inside the timeout
|
||||
set in stopAnalyticsThread.
|
||||
|
||||
@param eventsToSave the events that could not be logged
|
||||
|
||||
@see stopAnalyticsThread, stopLoggingEvents, restoreUnloggedEvents
|
||||
*/
|
||||
virtual void saveUnloggedEvents (const std::deque<AnalyticsEvent>& eventsToSave) = 0;
|
||||
|
||||
/**
|
||||
The counterpart to saveUnloggedEvents.
|
||||
|
||||
Events added to the event queue provided by this method will be the
|
||||
first events supplied to logBatchedEvents calls. Use this method to
|
||||
restore any unlogged events previously stored in a call to
|
||||
saveUnloggedEvents.
|
||||
|
||||
This method is called on the analytics thread.
|
||||
|
||||
@param restoredEventQueue place restored events into this queue
|
||||
|
||||
@see saveUnloggedEvents
|
||||
*/
|
||||
virtual void restoreUnloggedEvents (std::deque<AnalyticsEvent>& restoredEventQueue) = 0;
|
||||
|
||||
struct EventDispatcher : public Thread
|
||||
{
|
||||
EventDispatcher (const String& threadName, ThreadedAnalyticsDestination&);
|
||||
|
||||
void run() override;
|
||||
void addToQueue (const AnalyticsEvent&);
|
||||
|
||||
ThreadedAnalyticsDestination& parent;
|
||||
|
||||
std::deque<AnalyticsEvent> eventQueue;
|
||||
CriticalSection queueAccess;
|
||||
|
||||
Atomic<int> batchPeriodMilliseconds { 1000 };
|
||||
|
||||
Array<AnalyticsEvent> eventsToSend;
|
||||
};
|
||||
|
||||
const String destinationName;
|
||||
EventDispatcher dispatcher;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadedAnalyticsDestination)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
40
modules/juce_analytics/juce_analytics.cpp
Normal file
40
modules/juce_analytics/juce_analytics.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifdef JUCE_ANALYTICS_H_INCLUDED
|
||||
/* When you add this cpp file to your project, you mustn't include it in a file where you've
|
||||
already included any other headers - just put it inside a file on its own, possibly with your config
|
||||
flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix
|
||||
header files that the compiler may be using.
|
||||
*/
|
||||
#error "Incorrect use of JUCE cpp file"
|
||||
#endif
|
||||
|
||||
#include "juce_analytics.h"
|
||||
|
||||
#include "destinations/juce_ThreadedAnalyticsDestination.cpp"
|
||||
#include "analytics/juce_Analytics.cpp"
|
||||
#include "analytics/juce_ButtonTracker.cpp"
|
||||
56
modules/juce_analytics/juce_analytics.h
Normal file
56
modules/juce_analytics/juce_analytics.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
The block below describes the properties of this module, and is read by
|
||||
the Projucer to automatically generate project code that uses it.
|
||||
For details about the syntax and how to create or use a module, see the
|
||||
JUCE Module Format.txt file.
|
||||
|
||||
|
||||
BEGIN_JUCE_MODULE_DECLARATION
|
||||
|
||||
ID: juce_analytics
|
||||
vendor: juce
|
||||
version: 5.1.1
|
||||
name: JUCE analytics classes
|
||||
description: Classes to collect analytics and send to destinations
|
||||
website: http://www.juce.com/juce
|
||||
license: GPL/Commercial
|
||||
|
||||
dependencies: juce_gui_basics
|
||||
|
||||
END_JUCE_MODULE_DECLARATION
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#pragma once
|
||||
#define JUCE_ANALYTICS_H_INCLUDED
|
||||
|
||||
#include <queue>
|
||||
#include <juce_gui_basics/juce_gui_basics.h>
|
||||
|
||||
#include "destinations/juce_AnalyticsDestination.h"
|
||||
#include "destinations/juce_ThreadedAnalyticsDestination.h"
|
||||
#include "analytics/juce_Analytics.h"
|
||||
#include "analytics/juce_ButtonTracker.h"
|
||||
Loading…
Add table
Add a link
Reference in a new issue