├── VERSION
├── ios
├── Assets
│ └── .gitkeep
├── Classes
│ ├── AdjustSdk.h
│ └── AdjustSdkDelegate.h
└── adjust_sdk.podspec
├── test
├── ios
│ ├── Assets
│ │ └── .gitkeep
│ ├── AdjustTestLibrary.framework
│ │ ├── AdjustTestLibrary
│ │ ├── Versions
│ │ │ ├── A
│ │ │ │ ├── AdjustTestLibrary
│ │ │ │ └── Headers
│ │ │ │ │ ├── ATLBlockingQueue.h
│ │ │ │ │ ├── ATLControlWebSocketClient.h
│ │ │ │ │ ├── ATLUtil.h
│ │ │ │ │ ├── ATLConstants.h
│ │ │ │ │ ├── ATLNetworking.h
│ │ │ │ │ └── ATLTestLibrary.h
│ │ │ └── Current
│ │ │ │ ├── AdjustTestLibrary
│ │ │ │ └── Headers
│ │ │ │ ├── ATLBlockingQueue.h
│ │ │ │ ├── ATLControlWebSocketClient.h
│ │ │ │ ├── ATLUtil.h
│ │ │ │ ├── ATLConstants.h
│ │ │ │ ├── ATLNetworking.h
│ │ │ │ └── ATLTestLibrary.h
│ │ └── Headers
│ │ │ ├── ATLBlockingQueue.h
│ │ │ ├── ATLControlWebSocketClient.h
│ │ │ ├── ATLUtil.h
│ │ │ ├── ATLConstants.h
│ │ │ ├── ATLNetworking.h
│ │ │ └── ATLTestLibrary.h
│ ├── Classes
│ │ ├── TestLibPlugin.h
│ │ ├── AdjustCommandExecutor.h
│ │ ├── AdjustCommandExecutor.m
│ │ └── TestLibPlugin.m
│ └── test_lib.podspec
├── LICENSE
├── android
│ ├── gradle.properties
│ ├── settings.gradle
│ ├── src
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ └── com
│ │ │ └── adjust
│ │ │ └── test
│ │ │ └── lib
│ │ │ └── TestLibPlugin.java
│ ├── libs
│ │ ├── adjust-test-library.jar
│ │ └── adjust-test-options.jar
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── build.gradle
├── CHANGELOG.md
├── app
│ ├── ios
│ │ ├── Runner
│ │ │ ├── Runner-Bridging-Header.h
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── LaunchImage.imageset
│ │ │ │ │ ├── LaunchImage.png
│ │ │ │ │ ├── LaunchImage@2x.png
│ │ │ │ │ ├── LaunchImage@3x.png
│ │ │ │ │ ├── README.md
│ │ │ │ │ └── Contents.json
│ │ │ │ └── AppIcon.appiconset
│ │ │ │ │ ├── Icon-App-20x20@1x.png
│ │ │ │ │ ├── Icon-App-20x20@2x.png
│ │ │ │ │ ├── Icon-App-20x20@3x.png
│ │ │ │ │ ├── Icon-App-29x29@1x.png
│ │ │ │ │ ├── Icon-App-29x29@2x.png
│ │ │ │ │ ├── Icon-App-29x29@3x.png
│ │ │ │ │ ├── Icon-App-40x40@1x.png
│ │ │ │ │ ├── Icon-App-40x40@2x.png
│ │ │ │ │ ├── Icon-App-40x40@3x.png
│ │ │ │ │ ├── Icon-App-60x60@2x.png
│ │ │ │ │ ├── Icon-App-60x60@3x.png
│ │ │ │ │ ├── Icon-App-76x76@1x.png
│ │ │ │ │ ├── Icon-App-76x76@2x.png
│ │ │ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ │ │ └── Contents.json
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Base.lproj
│ │ │ │ ├── Main.storyboard
│ │ │ │ └── LaunchScreen.storyboard
│ │ │ └── Info.plist
│ │ ├── Flutter
│ │ │ ├── Debug.xcconfig
│ │ │ ├── Release.xcconfig
│ │ │ └── AppFrameworkInfo.plist
│ │ ├── Runner.xcodeproj
│ │ │ ├── project.xcworkspace
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata
│ │ │ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ └── xcshareddata
│ │ │ │ └── xcschemes
│ │ │ │ └── Runner.xcscheme
│ │ ├── Runner.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── Podfile
│ ├── android
│ │ ├── gradle
│ │ │ └── wrapper
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ ├── app
│ │ │ ├── src
│ │ │ │ ├── main
│ │ │ │ │ ├── res
│ │ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ │ ├── drawable
│ │ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ │ └── values
│ │ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── kotlin
│ │ │ │ │ │ └── com
│ │ │ │ │ │ │ └── adjust
│ │ │ │ │ │ │ └── examples
│ │ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ │ └── AndroidManifest.xml
│ │ │ │ ├── debug
│ │ │ │ │ └── AndroidManifest.xml
│ │ │ │ └── profile
│ │ │ │ │ └── AndroidManifest.xml
│ │ │ └── build.gradle.kts
│ │ ├── gradle.properties
│ │ ├── build.gradle.kts
│ │ ├── settings.gradle.kts
│ │ ├── gradlew.bat
│ │ └── gradlew
│ ├── pubspec.yaml
│ ├── .metadata
│ ├── README.md
│ └── lib
│ │ ├── command.dart
│ │ └── main.dart
├── README.md
├── pubspec.yaml
└── lib
│ └── test_lib.dart
├── android
├── gradle.properties
├── settings.gradle
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── adjust
│ │ └── sdk
│ │ └── flutter
│ │ └── AdjustUtils.java
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── build.gradle
├── example
├── ios
│ ├── Runner
│ │ ├── Runner-Bridging-Header.h
│ │ ├── Assets.xcassets
│ │ │ ├── LaunchImage.imageset
│ │ │ │ ├── LaunchImage.png
│ │ │ │ ├── LaunchImage@2x.png
│ │ │ │ ├── LaunchImage@3x.png
│ │ │ │ ├── README.md
│ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ ├── Icon-App-20x20@1x.png
│ │ │ │ ├── Icon-App-20x20@2x.png
│ │ │ │ ├── Icon-App-20x20@3x.png
│ │ │ │ ├── Icon-App-29x29@1x.png
│ │ │ │ ├── Icon-App-29x29@2x.png
│ │ │ │ ├── Icon-App-29x29@3x.png
│ │ │ │ ├── Icon-App-40x40@1x.png
│ │ │ │ ├── Icon-App-40x40@2x.png
│ │ │ │ ├── Icon-App-40x40@3x.png
│ │ │ │ ├── Icon-App-60x60@2x.png
│ │ │ │ ├── Icon-App-60x60@3x.png
│ │ │ │ ├── Icon-App-76x76@1x.png
│ │ │ │ ├── Icon-App-76x76@2x.png
│ │ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ │ └── Contents.json
│ │ ├── AppDelegate.swift
│ │ ├── Base.lproj
│ │ │ ├── Main.storyboard
│ │ │ └── LaunchScreen.storyboard
│ │ └── Info.plist
│ ├── Flutter
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── AppFrameworkInfo.plist
│ ├── Runner.xcodeproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ └── IDEWorkspaceChecks.plist
│ └── Podfile
├── android
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── app
│ │ ├── src
│ │ │ ├── main
│ │ │ │ ├── res
│ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── drawable
│ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ ├── drawable-v21
│ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ ├── values
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ └── values-night
│ │ │ │ │ │ └── styles.xml
│ │ │ │ ├── kotlin
│ │ │ │ │ └── com
│ │ │ │ │ │ └── adjust
│ │ │ │ │ │ └── examples
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── debug
│ │ │ │ └── AndroidManifest.xml
│ │ │ └── profile
│ │ │ │ └── AndroidManifest.xml
│ │ └── build.gradle.kts
│ ├── gradle.properties
│ ├── build.gradle.kts
│ ├── settings.gradle.kts
│ ├── gradlew.bat
│ └── gradlew
├── pubspec.yaml
├── .metadata
└── README.md
├── .gitmodules
├── README.md
├── .pubignore
├── pubspec.yaml
├── lib
├── adjust_deeplink.dart
├── adjust_app_store_purchase.dart
├── adjust_play_store_purchase.dart
├── adjust_store_info.dart
├── adjust_session_success.dart
├── adjust_session_failure.dart
├── adjust_event_success.dart
├── adjust_event_failure.dart
├── adjust_third_party_sharing.dart
├── adjust_purchase_verification_result.dart
├── adjust_app_store_subscription.dart
├── adjust_attribution.dart
├── adjust_play_store_subscription.dart
├── adjust_ad_revenue.dart
├── adjust_event.dart
└── adjust.dart
├── LICENSE
└── .gitignore
/VERSION:
--------------------------------------------------------------------------------
1 | 5.5.0
2 |
--------------------------------------------------------------------------------
/ios/Assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/ios/Assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/LICENSE:
--------------------------------------------------------------------------------
1 | TODO: Add your license here.
2 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'adjust_sdk'
2 |
--------------------------------------------------------------------------------
/test/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/test/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'test_lib'
2 |
--------------------------------------------------------------------------------
/test/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.0.1
2 |
3 | * TODO: Describe initial release.
4 |
--------------------------------------------------------------------------------
/example/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/test/app/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/test/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/test/android/libs/adjust-test-library.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/android/libs/adjust-test-library.jar
--------------------------------------------------------------------------------
/test/android/libs/adjust-test-options.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/android/libs/adjust-test-options.jar
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/test/app/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/test/app/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/test/app/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/AdjustTestLibrary:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/ios/AdjustTestLibrary.framework/AdjustTestLibrary
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/test/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/test/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/test/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/test/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/test/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/A/AdjustTestLibrary:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/ios/AdjustTestLibrary.framework/Versions/A/AdjustTestLibrary
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/Current/AdjustTestLibrary:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/ios/AdjustTestLibrary.framework/Versions/Current/AdjustTestLibrary
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/com/adjust/examples/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.adjust.examples
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity : FlutterActivity()
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/test/app/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/test/app/android/app/src/main/kotlin/com/adjust/examples/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.adjust.examples
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adjust/flutter_sdk/HEAD/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "ext/android/sdk"]
2 | path = ext/android/sdk
3 | url = https://github.com/adjust/android_sdk.git
4 | [submodule "ext/ios/sdk"]
5 | path = ext/ios/sdk
6 | url = https://github.com/adjust/ios_sdk.git
7 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip
6 |
--------------------------------------------------------------------------------
/test/app/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Adjust SDK for Flutter
2 |
3 | This is the [Adjust](https://adjust.com)™ SDK for Flutter. Documentation is available on our [developer docs](https://dev.adjust.com/en/sdk/flutter/?version=v5).
4 |
5 | ## License
6 |
7 | Distributed under the [`MIT license`](LICENSE).
8 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jan 06 12:48:45 CET 2025
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/ios/Classes/AdjustSdk.h:
--------------------------------------------------------------------------------
1 | //
2 | // AdjustSdk.h
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 6th June 2018.
6 | // Copyright © 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AdjustSdk : NSObject
12 | @end
13 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/test/app/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/test/app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/README.md:
--------------------------------------------------------------------------------
1 | # test_lib
2 |
3 | Flutter Plugin for Adjust Testing Library.
4 |
5 | ## Getting Started
6 |
7 | For help getting started with Flutter, view our online
8 | [documentation](https://flutter.io/).
9 |
10 | For help on editing plugin code, view the [documentation](https://flutter.io/developing-packages/#edit-plugin-package).
11 |
--------------------------------------------------------------------------------
/test/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/app/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/app/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/ios/Classes/TestLibPlugin.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestLibPlugin.h
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 1st October 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface TestLibPlugin : NSObject
13 | @end
14 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 |
4 | @main
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/app/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @main
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.pubignore:
--------------------------------------------------------------------------------
1 | # Exclude test directory from published package
2 | test/
3 |
4 | # Exclude external SDK submodules and scripts directory
5 | ext/
6 | scripts/
7 |
8 | # Exclude build artifacts and development files
9 | **/build/
10 | **/.dart_tool/
11 | **/Pods/
12 | **/.pub-cache/
13 | **/example/build/
14 | **/example/ios/build/
15 | **/example/android/build/
16 | **/example/.dart_tool/
17 | **/example/ios/Pods/
18 | **/example/ios/Podfile.lock
19 | **/example/android/local.properties
20 | **/*.iml
21 | **/.DS_Store
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/test/app/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: AdjustExample
2 | description: "Adjust Flutter Example App"
3 | publish_to: 'none'
4 | version: 0.0.1
5 |
6 | environment:
7 | sdk: ">=3.9.0 <4.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | adjust_sdk:
13 | path: ../
14 |
15 | dependency_overrides:
16 | characters: ^1.4.1
17 | material_color_utilities: ^0.13.0
18 | meta: ^1.17.0
19 |
20 | dev_dependencies:
21 | flutter_test:
22 | sdk: flutter
23 | flutter_lints: ^6.0.0
24 |
25 | flutter:
26 | uses-material-design: true
27 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: adjust_sdk
2 | description: This is the Flutter SDK of Adjust™. You can read more about Adjust™ at adjust.com.
3 | homepage: https://github.com/adjust/flutter_sdk
4 | version: 5.5.0
5 |
6 | environment:
7 | sdk: ">=2.12.0 <4.0.0"
8 | flutter: ">=1.10.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 | meta: ">=1.1.6 <2.0.0"
14 |
15 | flutter:
16 | plugin:
17 | platforms:
18 | android:
19 | package: com.adjust.sdk.flutter
20 | pluginClass: AdjustSdk
21 | ios:
22 | pluginClass: AdjustSdk
23 |
--------------------------------------------------------------------------------
/test/app/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: test_app
2 | description: "Adjust Flutter Test App"
3 | publish_to: 'none'
4 | version: 1.0.0+1
5 |
6 | environment:
7 | sdk: ">=3.9.0 <4.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | adjust_sdk:
13 | path: ../../
14 | test_lib:
15 | path: ../
16 |
17 | dependency_overrides:
18 | characters: ^1.4.1
19 | material_color_utilities: ^0.13.0
20 | meta: ^1.17.0
21 |
22 | dev_dependencies:
23 | flutter_test:
24 | sdk: flutter
25 | flutter_lints: ^6.0.0
26 |
27 | flutter:
28 | uses-material-design: true
29 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Headers/ATLBlockingQueue.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLBlockingQueue.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 11.01.18.
6 | // Copyright © 2018 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ATLUtil.h"
11 |
12 | @interface ATLBlockingQueue : NSObject
13 |
14 | /**
15 | * Enqueues an object to the queue.
16 | * @param object Object to enqueue
17 | */
18 | - (void)enqueue:(id)object;
19 |
20 | /**
21 | * Dequeues an object from the queue. This method will block.
22 | */
23 | - (id)dequeue;
24 |
25 | - (void)teardown;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/A/Headers/ATLBlockingQueue.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLBlockingQueue.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 11.01.18.
6 | // Copyright © 2018 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ATLUtil.h"
11 |
12 | @interface ATLBlockingQueue : NSObject
13 |
14 | /**
15 | * Enqueues an object to the queue.
16 | * @param object Object to enqueue
17 | */
18 | - (void)enqueue:(id)object;
19 |
20 | /**
21 | * Dequeues an object from the queue. This method will block.
22 | */
23 | - (id)dequeue;
24 |
25 | - (void)teardown;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/lib/adjust_deeplink.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_deeplink.dart
3 | // Adjust SDK
4 | //
5 | // Created by Ugljesa Erceg (@uerceg) on 19th August 2024.
6 | // Copyright (c) 2024-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustDeeplink {
10 | String deeplink;
11 | String? referrer;
12 |
13 | AdjustDeeplink(this.deeplink);
14 |
15 | Map get toMap {
16 | Map deeplinkMap = new Map();
17 |
18 | deeplinkMap['deeplink'] = deeplink;
19 | if (referrer != null) {
20 | deeplinkMap['referrer'] = referrer;
21 | }
22 |
23 | return deeplinkMap;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/Current/Headers/ATLBlockingQueue.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLBlockingQueue.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 11.01.18.
6 | // Copyright © 2018 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ATLUtil.h"
11 |
12 | @interface ATLBlockingQueue : NSObject
13 |
14 | /**
15 | * Enqueues an object to the queue.
16 | * @param object Object to enqueue
17 | */
18 | - (void)enqueue:(id)object;
19 |
20 | /**
21 | * Dequeues an object from the queue. This method will block.
22 | */
23 | - (id)dequeue;
24 |
25 | - (void)teardown;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/test/app/android/build.gradle.kts:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | val newBuildDir: Directory =
9 | rootProject.layout.buildDirectory
10 | .dir("../../build")
11 | .get()
12 | rootProject.layout.buildDirectory.value(newBuildDir)
13 |
14 | subprojects {
15 | val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
16 | project.layout.buildDirectory.value(newSubprojectBuildDir)
17 | }
18 | subprojects {
19 | project.evaluationDependsOn(":app")
20 | }
21 |
22 | tasks.register("clean") {
23 | delete(rootProject.layout.buildDirectory)
24 | }
--------------------------------------------------------------------------------
/example/android/build.gradle.kts:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | val newBuildDir: Directory =
9 | rootProject.layout.buildDirectory
10 | .dir("../../build")
11 | .get()
12 | rootProject.layout.buildDirectory.value(newBuildDir)
13 |
14 | subprojects {
15 | val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
16 | project.layout.buildDirectory.value(newSubprojectBuildDir)
17 | }
18 | subprojects {
19 | project.evaluationDependsOn(":app")
20 | }
21 |
22 | tasks.register("clean") {
23 | delete(rootProject.layout.buildDirectory)
24 | }
25 |
--------------------------------------------------------------------------------
/test/ios/Classes/AdjustCommandExecutor.h:
--------------------------------------------------------------------------------
1 | //
2 | // AdjustCommandExecutor.h
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 1st October 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 |
13 | @interface AdjustCommandExecutor : NSObject
14 |
15 | - (id)initWithMethodChannel:(FlutterMethodChannel *)channel;
16 | - (void)executeCommand:(NSString *)className
17 | methodName:(NSString *)methodName
18 | parameters:(NSString *)jsonParameters;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/lib/adjust_app_store_purchase.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_app_store_purchase.dart
3 | // Adjust SDK
4 | //
5 | // Created by Ugljesa Erceg (@uerceg) on 5th September 2023.
6 | // Copyright (c) 2020-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustAppStorePurchase {
10 | final String _productId;
11 | final String _transactionId;
12 |
13 | AdjustAppStorePurchase(this._productId, this._transactionId);
14 |
15 | Map get toMap {
16 | Map purchaseMap = new Map();
17 |
18 | purchaseMap['productId'] = _productId;
19 | purchaseMap['transactionId'] = _transactionId;
20 |
21 | return purchaseMap;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/adjust_play_store_purchase.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_play_store_purchase.dart
3 | // Adjust SDK
4 | //
5 | // Created by Ugljesa Erceg (@uerceg) on 4th September 2023.
6 | // Copyright (c) 2020-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustPlayStorePurchase {
10 | final String _productId;
11 | final String _purchaseToken;
12 |
13 | AdjustPlayStorePurchase(this._productId, this._purchaseToken);
14 |
15 | Map get toMap {
16 | Map purchaseMap = new Map();
17 |
18 | purchaseMap['productId'] = _productId;
19 | purchaseMap['purchaseToken'] = _purchaseToken;
20 |
21 | return purchaseMap;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/adjust_store_info.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_deeplink.dart
3 | // Adjust SDK
4 | //
5 | // Created by Mahdi ZTD (@MahdiZTD) on 6th June 2025.
6 | // Copyright (c) 2025-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustStoreInfo {
10 | String? storeName;
11 | String? storeAppId;
12 |
13 | AdjustStoreInfo(this.storeName);
14 |
15 | Map get toMap {
16 | Map storeInfoMap = new Map();
17 |
18 | if (storeName != null) {
19 | storeInfoMap['storeName'] = storeName;
20 | }
21 | if (storeAppId != null) {
22 | storeInfoMap['storeAppId'] = storeAppId;
23 | }
24 |
25 | return storeInfoMap;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Headers/ATLControlWebSocketClient.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLControlWebSocketClient.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Serj on 20.02.19.
6 | // Copyright © 2019 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "PocketSocket/PSWebSocket.h"
11 | #import "ATLTestLibrary.h"
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface ATLControlWebSocketClient : NSObject
16 |
17 | - (void)initializeWebSocketWithControlUrl:(NSString*)controlUrl
18 | andTestLibrary:(ATLTestLibrary*)testLibrary;
19 |
20 | - (void)reconnectIfNeeded;
21 |
22 | - (void)sendInitTestSessionSignal:(NSString*)testSessionId;
23 |
24 | @end
25 |
26 | NS_ASSUME_NONNULL_END
27 |
--------------------------------------------------------------------------------
/ios/adjust_sdk.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'adjust_sdk'
3 | s.version = '5.5.0'
4 | s.summary = 'Adjust Flutter SDK for iOS platform'
5 | s.description = <<-DESC
6 | Adjust Flutter SDK for iOS platform.
7 | DESC
8 | s.homepage = 'http://www.adjust.com'
9 | s.license = { :file => '../LICENSE' }
10 | s.author = { 'Adjust' => 'sdk@adjust.com' }
11 | s.source = { :path => '.' }
12 | s.source_files = 'Classes/**/*'
13 | s.public_header_files = 'Classes/**/*.h'
14 | s.ios.deployment_target = '12.0'
15 |
16 | s.dependency 'Flutter'
17 | s.dependency 'Adjust', '5.5.0'
18 | end
19 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/A/Headers/ATLControlWebSocketClient.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLControlWebSocketClient.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Serj on 20.02.19.
6 | // Copyright © 2019 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "PocketSocket/PSWebSocket.h"
11 | #import "ATLTestLibrary.h"
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface ATLControlWebSocketClient : NSObject
16 |
17 | - (void)initializeWebSocketWithControlUrl:(NSString*)controlUrl
18 | andTestLibrary:(ATLTestLibrary*)testLibrary;
19 |
20 | - (void)reconnectIfNeeded;
21 |
22 | - (void)sendInitTestSessionSignal:(NSString*)testSessionId;
23 |
24 | @end
25 |
26 | NS_ASSUME_NONNULL_END
27 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/Current/Headers/ATLControlWebSocketClient.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLControlWebSocketClient.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Serj on 20.02.19.
6 | // Copyright © 2019 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "PocketSocket/PSWebSocket.h"
11 | #import "ATLTestLibrary.h"
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface ATLControlWebSocketClient : NSObject
16 |
17 | - (void)initializeWebSocketWithControlUrl:(NSString*)controlUrl
18 | andTestLibrary:(ATLTestLibrary*)testLibrary;
19 |
20 | - (void)reconnectIfNeeded;
21 |
22 | - (void)sendInitTestSessionSignal:(NSString*)testSessionId;
23 |
24 | @end
25 |
26 | NS_ASSUME_NONNULL_END
27 |
--------------------------------------------------------------------------------
/test/app/android/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | val flutterSdkPath =
3 | run {
4 | val properties = java.util.Properties()
5 | file("local.properties").inputStream().use { properties.load(it) }
6 | val flutterSdkPath = properties.getProperty("flutter.sdk")
7 | require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
8 | flutterSdkPath
9 | }
10 |
11 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
12 |
13 | repositories {
14 | google()
15 | mavenCentral()
16 | gradlePluginPortal()
17 | }
18 | }
19 |
20 | plugins {
21 | id("dev.flutter.flutter-plugin-loader") version "1.0.0"
22 | id("com.android.application") version "8.13.0" apply false
23 | id("org.jetbrains.kotlin.android") version "2.1.0" apply false
24 | }
25 |
26 | include(":app")
--------------------------------------------------------------------------------
/example/android/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | val flutterSdkPath =
3 | run {
4 | val properties = java.util.Properties()
5 | file("local.properties").inputStream().use { properties.load(it) }
6 | val flutterSdkPath = properties.getProperty("flutter.sdk")
7 | require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
8 | flutterSdkPath
9 | }
10 |
11 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
12 |
13 | repositories {
14 | google()
15 | mavenCentral()
16 | gradlePluginPortal()
17 | }
18 | }
19 |
20 | plugins {
21 | id("dev.flutter.flutter-plugin-loader") version "1.0.0"
22 | id("com.android.application") version "8.13.0" apply false
23 | id("org.jetbrains.kotlin.android") version "2.1.0" apply false
24 | }
25 |
26 | include(":app")
27 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 13.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/android/src/main/java/com/adjust/sdk/flutter/AdjustUtils.java:
--------------------------------------------------------------------------------
1 | //
2 | // AdjustUtils.java
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 5th May 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | package com.adjust.sdk.flutter;
10 |
11 | import java.text.NumberFormat;
12 | import java.text.ParsePosition;
13 |
14 | public class AdjustUtils {
15 | private static NumberFormat numberFormat = NumberFormat.getInstance();
16 |
17 | public static boolean isNumber(String numberString) {
18 | if (numberString == null) {
19 | return false;
20 | }
21 | if (numberString.length() == 0) {
22 | return false;
23 | }
24 |
25 | ParsePosition position = new ParsePosition(0);
26 | numberFormat.parse(numberString, position);
27 | return numberString.length() == position.getIndex();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/app/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 13.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/ios/test_lib.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'test_lib'
3 | s.version = '5.5.0'
4 | s.summary = 'Adjust test library for iOS platform'
5 | s.description = <<-DESC
6 | Adjust test library for iOS platform.
7 | DESC
8 | s.homepage = 'http://www.adjust.com'
9 | s.license = { :file => '../LICENSE' }
10 | s.author = { 'Adjust' => 'sdk@adjust.com' }
11 | s.source = { :path => '.' }
12 | s.source_files = 'Classes/**/*'
13 | s.public_header_files = 'Classes/**/*.h'
14 | s.preserve_paths = 'AdjustTestLibrary.framework'
15 | s.xcconfig = { 'OTHER_LDFLAGS' => '-framework AdjustTestLibrary' }
16 | s.vendored_frameworks = 'AdjustTestLibrary.framework'
17 | s.ios.deployment_target = '8.0'
18 |
19 | s.dependency 'Flutter'
20 | end
21 |
--------------------------------------------------------------------------------
/lib/adjust_session_success.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_session_success.dart
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 25th April 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustSessionSuccess {
10 | final String? message;
11 | final String? timestamp;
12 | final String? adid;
13 | final String? jsonResponse;
14 |
15 | AdjustSessionSuccess({
16 | this.message,
17 | this.timestamp,
18 | this.adid,
19 | this.jsonResponse,
20 | });
21 |
22 | factory AdjustSessionSuccess.fromMap(dynamic map) {
23 | try {
24 | return AdjustSessionSuccess(
25 | message: map['message'],
26 | timestamp: map['timestamp'],
27 | adid: map['adid'],
28 | jsonResponse: map['jsonResponse'],
29 | );
30 | } catch (e) {
31 | throw Exception(
32 | '[AdjustFlutter]: Failed to create AdjustSessionSuccess object from given map object. Details: ' +
33 | e.toString());
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'com.adjust.sdk.flutter'
2 | version '1.0-SNAPSHOT'
3 | buildscript {
4 | repositories {
5 | google()
6 | mavenCentral()
7 | }
8 |
9 | dependencies {
10 | classpath('com.android.tools.build:gradle:8.13.0')
11 | }
12 | }
13 | rootProject.allprojects {
14 | repositories {
15 | google()
16 | mavenCentral()
17 | }
18 |
19 | gradle.projectsEvaluated {
20 | tasks.withType(JavaCompile) {
21 | options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
22 | }
23 | }
24 | }
25 | apply plugin: 'com.android.library'
26 | android {
27 | compileSdkVersion 36
28 |
29 | defaultConfig {
30 | minSdkVersion 16
31 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
32 | }
33 | lintOptions {
34 | disable 'InvalidPackage'
35 | }
36 | namespace 'com.adjust.sdk.flutter'
37 | }
38 |
39 | dependencies {
40 | implementation 'com.adjust.sdk:adjust-android:5.5.0'
41 | }
42 |
--------------------------------------------------------------------------------
/test/app/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/test/app/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: "761747bfc538b5af34aa0d3fac380f1bc331ec49"
8 | channel: "stable"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
17 | base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
18 | - platform: ios
19 | create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
20 | base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
21 |
22 | # User provided section
23 |
24 | # List of Local paths (relative to this file) that should be
25 | # ignored by the migrate tool.
26 | #
27 | # Files that are not part of the templates will be ignored by default.
28 | unmanaged_files:
29 | - 'lib/main.dart'
30 | - 'ios/Runner.xcodeproj/project.pbxproj'
31 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/test/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'com.adjust.test.lib'
2 | version '1.0-SNAPSHOT'
3 |
4 | buildscript {
5 | ext {
6 | agp_version = '8.2.1'
7 | }
8 | repositories {
9 | google()
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | classpath("com.android.tools.build:gradle:$agp_version")
15 | }
16 | }
17 |
18 | rootProject.allprojects {
19 | repositories {
20 | google()
21 | mavenCentral()
22 | }
23 | }
24 |
25 | apply plugin: 'com.android.library'
26 |
27 | android {
28 | namespace 'com.adjust.test.lib'
29 | compileSdk = 34
30 |
31 | defaultConfig {
32 | minSdkVersion 16
33 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
34 | }
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 | namespace 'com.adjust.examples'
39 | }
40 |
41 | dependencies {
42 | implementation files('libs/adjust-test-library.jar')
43 | implementation files('libs/adjust-test-options.jar')
44 | implementation 'com.google.code.gson:gson:2.8.6'
45 | implementation 'org.java-websocket:Java-WebSocket:1.4.0'
46 | }
--------------------------------------------------------------------------------
/lib/adjust_session_failure.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_session_failure.dart
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 25th April 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustSessionFailure {
10 | final String? message;
11 | final String? timestamp;
12 | final String? adid;
13 | final String? jsonResponse;
14 | final bool? willRetry;
15 |
16 | AdjustSessionFailure({
17 | this.message,
18 | this.timestamp,
19 | this.adid,
20 | this.jsonResponse,
21 | this.willRetry,
22 | });
23 |
24 | factory AdjustSessionFailure.fromMap(dynamic map) {
25 | try {
26 | return AdjustSessionFailure(
27 | message: map['message'],
28 | timestamp: map['timestamp'],
29 | adid: map['adid'],
30 | jsonResponse: map['jsonResponse'],
31 | willRetry: map['willRetry']?.toString().toLowerCase() == 'true',
32 | );
33 | } catch (e) {
34 | throw Exception(
35 | '[AdjustFlutter]: Failed to create AdjustSessionFailure object from given map object. Details: ' +
36 | e.toString());
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018-Present Adjust GmbH, http://www.adjust.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Headers/ATLUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLUtil.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 18.04.17.
6 | // Copyright © 2017 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef void (^selfInjectedBlock)(id);
12 | typedef void (^operationBlock)(NSBlockOperation *);
13 |
14 | @interface ATLUtil : NSObject
15 |
16 | + (void)debug:(NSString *)format, ...;
17 | + (void)launchInQueue:(dispatch_queue_t)queue
18 | selfInject:(id)selfInject
19 | block:(selfInjectedBlock)block;
20 | + (void)addOperationAfterLast:(NSOperationQueue *)operationQueue
21 | block:(dispatch_block_t)block;
22 | + (void)addOperationAfterLast:(NSOperationQueue *)operationQueue
23 | blockWithOperation:(operationBlock)blockWithOperation;
24 | + (BOOL)isNull:(id)value;
25 | + (NSString *)adjTrim:(NSString *)value;
26 | + (NSString *)formatDate:(NSDate *)value;
27 | + (NSString *)parseDictionaryToJsonString:(NSDictionary *) dictionary;
28 | + (NSString *)appendBasePath:(NSString *)basePath path:(NSString *)path;
29 | + (NSString *)queryString:(NSDictionary *)parameters;
30 | @end
31 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/A/Headers/ATLUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLUtil.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 18.04.17.
6 | // Copyright © 2017 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef void (^selfInjectedBlock)(id);
12 | typedef void (^operationBlock)(NSBlockOperation *);
13 |
14 | @interface ATLUtil : NSObject
15 |
16 | + (void)debug:(NSString *)format, ...;
17 | + (void)launchInQueue:(dispatch_queue_t)queue
18 | selfInject:(id)selfInject
19 | block:(selfInjectedBlock)block;
20 | + (void)addOperationAfterLast:(NSOperationQueue *)operationQueue
21 | block:(dispatch_block_t)block;
22 | + (void)addOperationAfterLast:(NSOperationQueue *)operationQueue
23 | blockWithOperation:(operationBlock)blockWithOperation;
24 | + (BOOL)isNull:(id)value;
25 | + (NSString *)adjTrim:(NSString *)value;
26 | + (NSString *)formatDate:(NSDate *)value;
27 | + (NSString *)parseDictionaryToJsonString:(NSDictionary *) dictionary;
28 | + (NSString *)appendBasePath:(NSString *)basePath path:(NSString *)path;
29 | + (NSString *)queryString:(NSDictionary *)parameters;
30 | @end
31 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/Current/Headers/ATLUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLUtil.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 18.04.17.
6 | // Copyright © 2017 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef void (^selfInjectedBlock)(id);
12 | typedef void (^operationBlock)(NSBlockOperation *);
13 |
14 | @interface ATLUtil : NSObject
15 |
16 | + (void)debug:(NSString *)format, ...;
17 | + (void)launchInQueue:(dispatch_queue_t)queue
18 | selfInject:(id)selfInject
19 | block:(selfInjectedBlock)block;
20 | + (void)addOperationAfterLast:(NSOperationQueue *)operationQueue
21 | block:(dispatch_block_t)block;
22 | + (void)addOperationAfterLast:(NSOperationQueue *)operationQueue
23 | blockWithOperation:(operationBlock)blockWithOperation;
24 | + (BOOL)isNull:(id)value;
25 | + (NSString *)adjTrim:(NSString *)value;
26 | + (NSString *)formatDate:(NSDate *)value;
27 | + (NSString *)parseDictionaryToJsonString:(NSDictionary *) dictionary;
28 | + (NSString *)appendBasePath:(NSString *)basePath path:(NSString *)path;
29 | + (NSString *)queryString:(NSDictionary *)parameters;
30 | @end
31 |
--------------------------------------------------------------------------------
/lib/adjust_event_success.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_event_success.dart
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 25th April 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustEventSuccess {
10 | final String? message;
11 | final String? timestamp;
12 | final String? adid;
13 | final String? eventToken;
14 | final String? callbackId;
15 | final String? jsonResponse;
16 |
17 | AdjustEventSuccess({
18 | this.message,
19 | this.timestamp,
20 | this.adid,
21 | this.eventToken,
22 | this.callbackId,
23 | this.jsonResponse,
24 | });
25 |
26 | factory AdjustEventSuccess.fromMap(dynamic map) {
27 | try {
28 | return AdjustEventSuccess(
29 | message: map['message'],
30 | timestamp: map['timestamp'],
31 | adid: map['adid'],
32 | eventToken: map['eventToken'],
33 | callbackId: map['callbackId'],
34 | jsonResponse: map['jsonResponse'],
35 | );
36 | } catch (e) {
37 | throw Exception(
38 | '[AdjustFlutter]: Failed to create AdjustEventSuccess object from given map object. Details: ' +
39 | e.toString());
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Headers/ATLConstants.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLConstants.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 20.04.17.
6 | // Copyright © 2017 adjust. All rights reserved.
7 | //
8 |
9 | #ifndef ATLConstants_h
10 | #define ATLConstants_h
11 |
12 | static int const ONE_SECOND = 1000;
13 | static int const ONE_MINUTE = 60 * ONE_SECOND;
14 |
15 | static NSString * const TEST_LIBRARY_CLASSNAME = @"TestLibrary";
16 | static NSString * const ADJUST_CLASSNAME = @"Adjust";
17 | static NSString * const WAIT_FOR_CONTROL = @"control";
18 | static NSString * const WAIT_FOR_SLEEP = @"sleep";
19 | static NSString * const BASE_PATH_PARAM = @"basePath";
20 | static NSString * const TEST_NAME_PARAM = @"basePath";
21 | static NSString * const TEST_SESSION_ID_HEADER = @"Test-Session-Id";
22 |
23 | // web socket values
24 | static NSString * const SIGNAL_INFO = @"info";
25 | static NSString * const SIGNAL_INIT_TEST_SESSION = @"init-test-session";
26 | static NSString * const SIGNAL_END_WAIT = @"end-wait";
27 | static NSString * const SIGNAL_CANCEL_CURRENT_TEST = @"cancel-current-test";
28 | static NSString * const SIGNAL_UNKNOWN = @"unknown";
29 |
30 | #endif /* ATLConstants_h */
31 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/A/Headers/ATLConstants.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLConstants.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 20.04.17.
6 | // Copyright © 2017 adjust. All rights reserved.
7 | //
8 |
9 | #ifndef ATLConstants_h
10 | #define ATLConstants_h
11 |
12 | static int const ONE_SECOND = 1000;
13 | static int const ONE_MINUTE = 60 * ONE_SECOND;
14 |
15 | static NSString * const TEST_LIBRARY_CLASSNAME = @"TestLibrary";
16 | static NSString * const ADJUST_CLASSNAME = @"Adjust";
17 | static NSString * const WAIT_FOR_CONTROL = @"control";
18 | static NSString * const WAIT_FOR_SLEEP = @"sleep";
19 | static NSString * const BASE_PATH_PARAM = @"basePath";
20 | static NSString * const TEST_NAME_PARAM = @"basePath";
21 | static NSString * const TEST_SESSION_ID_HEADER = @"Test-Session-Id";
22 |
23 | // web socket values
24 | static NSString * const SIGNAL_INFO = @"info";
25 | static NSString * const SIGNAL_INIT_TEST_SESSION = @"init-test-session";
26 | static NSString * const SIGNAL_END_WAIT = @"end-wait";
27 | static NSString * const SIGNAL_CANCEL_CURRENT_TEST = @"cancel-current-test";
28 | static NSString * const SIGNAL_UNKNOWN = @"unknown";
29 |
30 | #endif /* ATLConstants_h */
31 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/Current/Headers/ATLConstants.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLConstants.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 20.04.17.
6 | // Copyright © 2017 adjust. All rights reserved.
7 | //
8 |
9 | #ifndef ATLConstants_h
10 | #define ATLConstants_h
11 |
12 | static int const ONE_SECOND = 1000;
13 | static int const ONE_MINUTE = 60 * ONE_SECOND;
14 |
15 | static NSString * const TEST_LIBRARY_CLASSNAME = @"TestLibrary";
16 | static NSString * const ADJUST_CLASSNAME = @"Adjust";
17 | static NSString * const WAIT_FOR_CONTROL = @"control";
18 | static NSString * const WAIT_FOR_SLEEP = @"sleep";
19 | static NSString * const BASE_PATH_PARAM = @"basePath";
20 | static NSString * const TEST_NAME_PARAM = @"basePath";
21 | static NSString * const TEST_SESSION_ID_HEADER = @"Test-Session-Id";
22 |
23 | // web socket values
24 | static NSString * const SIGNAL_INFO = @"info";
25 | static NSString * const SIGNAL_INIT_TEST_SESSION = @"init-test-session";
26 | static NSString * const SIGNAL_END_WAIT = @"end-wait";
27 | static NSString * const SIGNAL_CANCEL_CURRENT_TEST = @"cancel-current-test";
28 | static NSString * const SIGNAL_UNKNOWN = @"unknown";
29 |
30 | #endif /* ATLConstants_h */
31 |
--------------------------------------------------------------------------------
/lib/adjust_event_failure.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_event_failure.dart
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 25th April 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustEventFailure {
10 | final String? message;
11 | final String? timestamp;
12 | final String? adid;
13 | final String? eventToken;
14 | final String? callbackId;
15 | final String? jsonResponse;
16 | final bool? willRetry;
17 |
18 | AdjustEventFailure({
19 | this.message,
20 | this.timestamp,
21 | this.adid,
22 | this.eventToken,
23 | this.callbackId,
24 | this.jsonResponse,
25 | this.willRetry,
26 | });
27 |
28 | factory AdjustEventFailure.fromMap(dynamic map) {
29 | try {
30 | return AdjustEventFailure(
31 | message: map['message'],
32 | timestamp: map['timestamp'],
33 | adid: map['adid'],
34 | eventToken: map['eventToken'],
35 | callbackId: map['callbackId'],
36 | jsonResponse: map['jsonResponse'],
37 | willRetry: map['willRetry']?.toString().toLowerCase() == 'true',
38 | );
39 | } catch (e) {
40 | throw Exception(
41 | '[AdjustFlutter]: Failed to create AdjustEventFailure object from given map object. Details: ' +
42 | e.toString());
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.application")
3 | id("kotlin-android")
4 | // the Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins
5 | id("dev.flutter.flutter-gradle-plugin")
6 | }
7 |
8 | android {
9 | namespace = "com.adjust.examples"
10 | // compileSdk = flutter.compileSdkVersion
11 | compileSdk = 36
12 | ndkVersion = flutter.ndkVersion
13 |
14 | compileOptions {
15 | sourceCompatibility = JavaVersion.VERSION_11
16 | targetCompatibility = JavaVersion.VERSION_11
17 | }
18 |
19 | kotlinOptions {
20 | jvmTarget = JavaVersion.VERSION_11.toString()
21 | }
22 |
23 | defaultConfig {
24 | applicationId = "com.adjust.examples"
25 | minSdk = flutter.minSdkVersion
26 | // targetSdk = flutter.targetSdkVersion
27 | targetSdk = 36
28 | versionCode = flutter.versionCode
29 | versionName = flutter.versionName
30 | }
31 |
32 | buildTypes {
33 | release {
34 | // signing with debug keys for development convenience
35 | signingConfig = signingConfigs.getByName("debug")
36 | }
37 | }
38 | }
39 |
40 | flutter {
41 | source = "../.."
42 | }
43 |
44 | dependencies {
45 | implementation("com.adjust.sdk:adjust-android-google-lvl:5.5.0")
46 | }
47 |
--------------------------------------------------------------------------------
/ios/Classes/AdjustSdkDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AdjustSdkDelegate.h
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (2beens) on 22nd November 2018.
6 | // Copyright © 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface AdjustSdkDelegate : NSObject
13 |
14 | @property (nonatomic) BOOL shouldLaunchDeferredDeeplink;
15 | @property (nonatomic, weak) FlutterMethodChannel *channel;
16 |
17 | + (id)getInstanceWithSwizzleOfAttributionCallback:(NSString *)swizzleAttributionCallback
18 | sessionSuccessCallback:(NSString *)swizzleSessionSuccessCallback
19 | sessionFailureCallback:(NSString *)swizzleSessionFailureCallback
20 | eventSuccessCallback:(NSString *)swizzleEventSuccessCallback
21 | eventFailureCallback:(NSString *)swizzleEventFailureCallback
22 | deferredDeeplinkCallback:(NSString *)swizzleDeferredDeeplinkCallback
23 | skanUpdatedCallback:(NSString *)swizzleSkanUpdatedCallback
24 | shouldLaunchDeferredDeeplink:(BOOL)shouldLaunchDeferredDeeplink
25 | methodChannel:(FlutterMethodChannel *)channel;
26 |
27 | + (void)teardown;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Headers/ATLNetworking.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLNetworking.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro Silva on 24.05.24.
6 | // Copyright © 2024 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ATLHttpResponse : NSObject
12 |
13 | @property (nonatomic, nullable, strong) NSString * responseString;
14 | @property (nonatomic, nullable, strong) id jsonFoundation;
15 | @property (nonatomic, nullable, strong) NSDictionary *headerFields;
16 | @property (nonatomic, assign) NSInteger statusCode;
17 |
18 | @end
19 |
20 | @interface ATLHttpRequest : NSObject
21 |
22 | @property (nonatomic, nonnull, readonly, strong) NSString *path;
23 | @property (nonatomic, nullable, readonly, strong) NSString *base;
24 | @property (nonatomic, nullable, strong) NSString *bodyString;
25 | @property (nonatomic, nullable, strong) NSDictionary *headerFields;
26 |
27 | - (nonnull id)initWithPath:(nonnull NSString *)path
28 | base:(nullable NSString *)base;
29 | @end
30 |
31 | typedef void (^httpResponseHandler)(ATLHttpResponse *_Nonnull httpResponse);
32 |
33 | @interface ATLNetworking : NSObject
34 |
35 | - (void)sendPostRequestWithData:(nonnull ATLHttpRequest *)requestData
36 | baseUrl:(nonnull NSURL *)baseUrl
37 | responseHandler:(nonnull httpResponseHandler)responseHandler;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/A/Headers/ATLNetworking.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLNetworking.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro Silva on 24.05.24.
6 | // Copyright © 2024 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ATLHttpResponse : NSObject
12 |
13 | @property (nonatomic, nullable, strong) NSString * responseString;
14 | @property (nonatomic, nullable, strong) id jsonFoundation;
15 | @property (nonatomic, nullable, strong) NSDictionary *headerFields;
16 | @property (nonatomic, assign) NSInteger statusCode;
17 |
18 | @end
19 |
20 | @interface ATLHttpRequest : NSObject
21 |
22 | @property (nonatomic, nonnull, readonly, strong) NSString *path;
23 | @property (nonatomic, nullable, readonly, strong) NSString *base;
24 | @property (nonatomic, nullable, strong) NSString *bodyString;
25 | @property (nonatomic, nullable, strong) NSDictionary *headerFields;
26 |
27 | - (nonnull id)initWithPath:(nonnull NSString *)path
28 | base:(nullable NSString *)base;
29 | @end
30 |
31 | typedef void (^httpResponseHandler)(ATLHttpResponse *_Nonnull httpResponse);
32 |
33 | @interface ATLNetworking : NSObject
34 |
35 | - (void)sendPostRequestWithData:(nonnull ATLHttpRequest *)requestData
36 | baseUrl:(nonnull NSURL *)baseUrl
37 | responseHandler:(nonnull httpResponseHandler)responseHandler;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/Current/Headers/ATLNetworking.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATLNetworking.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro Silva on 24.05.24.
6 | // Copyright © 2024 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ATLHttpResponse : NSObject
12 |
13 | @property (nonatomic, nullable, strong) NSString * responseString;
14 | @property (nonatomic, nullable, strong) id jsonFoundation;
15 | @property (nonatomic, nullable, strong) NSDictionary *headerFields;
16 | @property (nonatomic, assign) NSInteger statusCode;
17 |
18 | @end
19 |
20 | @interface ATLHttpRequest : NSObject
21 |
22 | @property (nonatomic, nonnull, readonly, strong) NSString *path;
23 | @property (nonatomic, nullable, readonly, strong) NSString *base;
24 | @property (nonatomic, nullable, strong) NSString *bodyString;
25 | @property (nonatomic, nullable, strong) NSDictionary *headerFields;
26 |
27 | - (nonnull id)initWithPath:(nonnull NSString *)path
28 | base:(nullable NSString *)base;
29 | @end
30 |
31 | typedef void (^httpResponseHandler)(ATLHttpResponse *_Nonnull httpResponse);
32 |
33 | @interface ATLNetworking : NSObject
34 |
35 | - (void)sendPostRequestWithData:(nonnull ATLHttpRequest *)requestData
36 | baseUrl:(nonnull NSURL *)baseUrl
37 | responseHandler:(nonnull httpResponseHandler)responseHandler;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/test/ios/Classes/AdjustCommandExecutor.m:
--------------------------------------------------------------------------------
1 | //
2 | // AdjustCommandExecutor.m
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 1st October 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AdjustCommandExecutor.h"
11 |
12 | @interface AdjustCommandExecutor ()
13 |
14 | @property(nonatomic, weak) FlutterMethodChannel *channel;
15 |
16 | @end
17 |
18 | @implementation AdjustCommandExecutor
19 | - (id)initWithMethodChannel:(FlutterMethodChannel *)channel {
20 | self = [super init];
21 | if (self == nil) {
22 | return nil;
23 | }
24 |
25 | NSLog(@"Initializing Test Library with Method Channel ...");
26 | self.channel = channel;
27 | return self;
28 | }
29 |
30 | - (void)executeCommand:(NSString *)className
31 | methodName:(NSString *)methodName
32 | parameters:(NSString *)jsonParameters {
33 | NSLog(@"executeCommand className: %@, methodName: %@, parameters: %@", className, methodName, jsonParameters);
34 | NSMutableDictionary *methodParams = [[NSMutableDictionary alloc] init];
35 | [methodParams setObject:className forKey:@"className"];
36 | [methodParams setObject:methodName forKey:@"methodName"];
37 | [methodParams setObject:jsonParameters forKey:@"jsonParameters"];
38 | [self.channel invokeMethod:@"adj-test-execute" arguments:methodParams];
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/test/app/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '13.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 |
33 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
34 | end
35 |
36 | post_install do |installer|
37 | installer.pods_project.targets.each do |target|
38 | flutter_additional_ios_build_settings(target)
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/lib/adjust_third_party_sharing.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_third_party_sharing.dart
3 | // Adjust SDK
4 | //
5 | // Created by Ugljesa Erceg (@uerceg) on 18th February 2021.
6 | // Copyright (c) 2021-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustThirdPartySharing {
10 | final bool? _isEnabled;
11 | late List _granularOptions;
12 | late List _partnerSharingSettings;
13 |
14 | AdjustThirdPartySharing(this._isEnabled) {
15 | _granularOptions = [];
16 | _partnerSharingSettings = [];
17 | }
18 |
19 | void addGranularOption(String partnerName, String key, String value) {
20 | _granularOptions.add(partnerName);
21 | _granularOptions.add(key);
22 | _granularOptions.add(value);
23 | }
24 |
25 | void addPartnerSharingSetting(String partnerName, String key, bool value) {
26 | _partnerSharingSettings.add(partnerName);
27 | _partnerSharingSettings.add(key);
28 | _partnerSharingSettings.add(value.toString());
29 | }
30 |
31 | Map get toMap {
32 | Map thirdPartySharingMap = {'isEnabled': _isEnabled};
33 | if (_granularOptions.length > 0) {
34 | thirdPartySharingMap['granularOptions'] =
35 | _granularOptions.join('__ADJ__');
36 | }
37 | if (_partnerSharingSettings.length > 0) {
38 | thirdPartySharingMap['partnerSharingSettings'] =
39 | _partnerSharingSettings.join('__ADJ__');
40 | }
41 |
42 | return thirdPartySharingMap;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/adjust_purchase_verification_result.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_purchase_verification_result.dart
3 | // Adjust SDK
4 | //
5 | // Created by Ugljesa Erceg (@uerceg) on 4th September 2020.
6 | // Copyright (c) 2020-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustPurchaseVerificationResult {
10 | final num code;
11 | final String message;
12 | final String verificationStatus;
13 |
14 | AdjustPurchaseVerificationResult(this.code, this.message, this.verificationStatus);
15 |
16 | factory AdjustPurchaseVerificationResult.fromMap(dynamic map) {
17 | try {
18 | int parsedCode = -1;
19 | try {
20 | if (map['code'] != null) {
21 | parsedCode = int.parse(map['code']);
22 | }
23 | } catch (ex) {}
24 |
25 | return AdjustPurchaseVerificationResult(
26 | parsedCode,
27 | map['message'] ?? '',
28 | map['verificationStatus'] ?? '');
29 | } catch (e) {
30 | throw Exception(
31 | '[AdjustFlutter]: Failed to create AdjustPurchaseVerificationResult object from given map object. Details: ' +
32 | e.toString());
33 | }
34 | }
35 |
36 | Map get toMap {
37 | Map verificationInfoMap = new Map();
38 |
39 | verificationInfoMap['code'] = code.toString();
40 | verificationInfoMap['message'] = message;
41 | verificationInfoMap['verificationStatus'] = verificationStatus;
42 |
43 | return verificationInfoMap;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '13.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 |
33 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
34 | target 'RunnerTests' do
35 | inherit! :search_paths
36 | end
37 | end
38 |
39 | post_install do |installer|
40 | installer.pods_project.targets.each do |target|
41 | flutter_additional_ios_build_settings(target)
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/test/app/README.md:
--------------------------------------------------------------------------------
1 | # Adjust Flutter Test App
2 |
3 | A comprehensive test application for the Adjust Flutter SDK, designed to validate SDK functionality through automated testing.
4 |
5 | ## Features
6 |
7 | - **Automated Test Execution**: Connects to test framework for automated SDK testing
8 | - **Modern UI**: Clean, modern interface following Adjust design guidelines
9 | - **Cross-Platform**: Supports both Android and iOS testing scenarios
10 | - **Real-time Command Processing**: Executes test commands in real-time from test server
11 |
12 | ## Getting Started
13 |
14 | 1. **Prerequisites**: Make sure Flutter is installed and configured
15 | 2. **Install Dependencies**: Run `flutter pub get` in this directory
16 | 3. **Configure Test Server**: Update IP addresses in `main.dart` if needed
17 | 4. **Run the App**: Use `flutter run` to start the test application
18 |
19 | ## Test Configuration
20 |
21 | The app connects to a test server for automated command execution:
22 | - **Android**: Uses HTTPS connection on port 8443
23 | - **iOS**: Uses HTTP connection on port 8080
24 | - **WebSocket**: Control connection on port 1987
25 |
26 | ## Architecture
27 |
28 | - `main.dart`: Main app entry point with modern UI
29 | - `command.dart`: Command parsing and representation
30 | - `command_executor.dart`: SDK method execution engine
31 | - Test framework integration via `test_lib` package
32 |
33 | ## Usage
34 |
35 | 1. Launch the app
36 | 2. Tap "Start Test Session" to begin automated testing
37 | 3. The app will connect to the test server and execute commands automatically
38 | 4. Monitor console output for test execution details
39 |
--------------------------------------------------------------------------------
/test/app/android/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.application")
3 | id("kotlin-android")
4 | // the Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins
5 | id("dev.flutter.flutter-gradle-plugin")
6 | }
7 |
8 | android {
9 | namespace = "com.adjust.examples"
10 | // compileSdk = flutter.compileSdkVersion
11 | compileSdk = 36
12 | ndkVersion = flutter.ndkVersion
13 |
14 | compileOptions {
15 | sourceCompatibility = JavaVersion.VERSION_11
16 | targetCompatibility = JavaVersion.VERSION_11
17 | }
18 |
19 | kotlinOptions {
20 | jvmTarget = JavaVersion.VERSION_11.toString()
21 | }
22 |
23 | defaultConfig {
24 | applicationId = "com.adjust.examples"
25 | minSdk = flutter.minSdkVersion
26 | // targetSdk = flutter.targetSdkVersion
27 | targetSdk = 36
28 | versionCode = flutter.versionCode
29 | versionName = flutter.versionName
30 | }
31 |
32 | buildTypes {
33 | release {
34 | signingConfig = signingConfigs.getByName("debug")
35 | }
36 | }
37 |
38 | lint {
39 | disable.add("InvalidPackage")
40 | }
41 | }
42 |
43 | flutter {
44 | source = "../.."
45 | }
46 |
47 | dependencies {
48 | // google Play Services for analytics
49 | implementation("com.google.android.gms:play-services-analytics:18.0.1")
50 |
51 | // install referrer for attribution
52 | implementation("com.android.installreferrer:installreferrer:2.2")
53 |
54 | // modern logging framework
55 | implementation("org.slf4j:slf4j-simple:2.0.9")
56 | }
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Headers/ATLTestLibrary.h:
--------------------------------------------------------------------------------
1 | //
2 | // AdjustTestLibrary.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 18.04.17.
6 | // Copyright © 2017 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ATLNetworking.h"
11 | #import "ATLBlockingQueue.h"
12 |
13 | @protocol AdjustCommandDelegate
14 | @optional
15 | - (void)executeCommand:(NSString *)className
16 | methodName:(NSString *)methodName
17 | parameters:(NSDictionary *)parameters;
18 |
19 | - (void)executeCommand:(NSString *)className
20 | methodName:(NSString *)methodName
21 | jsonParameters:(NSString *)jsonParameters;
22 |
23 | - (void)executeCommandRawJson:(NSString *)json;
24 | @end
25 |
26 | @interface ATLTestLibrary : NSObject
27 |
28 | - (NSString *)currentBasePath;
29 |
30 | - (ATLBlockingQueue *)waitControlQueue;
31 |
32 | - (void)addTest:(NSString *)testName;
33 |
34 | - (void)addTestDirectory:(NSString *)testDirectory;
35 |
36 | - (void)startTestSession:(NSString *)clientSdk;
37 |
38 | - (void)resetTestLibrary;
39 |
40 | - (void)readResponse:(ATLHttpResponse *)httpResponse;
41 |
42 | - (void)addInfoToSend:(NSString *)key
43 | value:(NSString *)value;
44 |
45 | - (void)sendInfoToServer:(NSString *)basePath;
46 |
47 | - (void)signalEndWaitWithReason:(NSString *)reason;
48 |
49 | - (void)cancelTestAndGetNext;
50 |
51 | - (void)doNotExitAfterEnd;
52 |
53 | + (ATLTestLibrary *)testLibraryWithBaseUrl:(NSString *)baseUrl
54 | andControlUrl:(NSString *)controlUrl
55 | andCommandDelegate:(NSObject *)commandDelegate;
56 | @end
57 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/app/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/A/Headers/ATLTestLibrary.h:
--------------------------------------------------------------------------------
1 | //
2 | // AdjustTestLibrary.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 18.04.17.
6 | // Copyright © 2017 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ATLNetworking.h"
11 | #import "ATLBlockingQueue.h"
12 |
13 | @protocol AdjustCommandDelegate
14 | @optional
15 | - (void)executeCommand:(NSString *)className
16 | methodName:(NSString *)methodName
17 | parameters:(NSDictionary *)parameters;
18 |
19 | - (void)executeCommand:(NSString *)className
20 | methodName:(NSString *)methodName
21 | jsonParameters:(NSString *)jsonParameters;
22 |
23 | - (void)executeCommandRawJson:(NSString *)json;
24 | @end
25 |
26 | @interface ATLTestLibrary : NSObject
27 |
28 | - (NSString *)currentBasePath;
29 |
30 | - (ATLBlockingQueue *)waitControlQueue;
31 |
32 | - (void)addTest:(NSString *)testName;
33 |
34 | - (void)addTestDirectory:(NSString *)testDirectory;
35 |
36 | - (void)startTestSession:(NSString *)clientSdk;
37 |
38 | - (void)resetTestLibrary;
39 |
40 | - (void)readResponse:(ATLHttpResponse *)httpResponse;
41 |
42 | - (void)addInfoToSend:(NSString *)key
43 | value:(NSString *)value;
44 |
45 | - (void)sendInfoToServer:(NSString *)basePath;
46 |
47 | - (void)signalEndWaitWithReason:(NSString *)reason;
48 |
49 | - (void)cancelTestAndGetNext;
50 |
51 | - (void)doNotExitAfterEnd;
52 |
53 | + (ATLTestLibrary *)testLibraryWithBaseUrl:(NSString *)baseUrl
54 | andControlUrl:(NSString *)controlUrl
55 | andCommandDelegate:(NSObject *)commandDelegate;
56 | @end
57 |
--------------------------------------------------------------------------------
/test/ios/AdjustTestLibrary.framework/Versions/Current/Headers/ATLTestLibrary.h:
--------------------------------------------------------------------------------
1 | //
2 | // AdjustTestLibrary.h
3 | // AdjustTestLibrary
4 | //
5 | // Created by Pedro on 18.04.17.
6 | // Copyright © 2017 adjust. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ATLNetworking.h"
11 | #import "ATLBlockingQueue.h"
12 |
13 | @protocol AdjustCommandDelegate
14 | @optional
15 | - (void)executeCommand:(NSString *)className
16 | methodName:(NSString *)methodName
17 | parameters:(NSDictionary *)parameters;
18 |
19 | - (void)executeCommand:(NSString *)className
20 | methodName:(NSString *)methodName
21 | jsonParameters:(NSString *)jsonParameters;
22 |
23 | - (void)executeCommandRawJson:(NSString *)json;
24 | @end
25 |
26 | @interface ATLTestLibrary : NSObject
27 |
28 | - (NSString *)currentBasePath;
29 |
30 | - (ATLBlockingQueue *)waitControlQueue;
31 |
32 | - (void)addTest:(NSString *)testName;
33 |
34 | - (void)addTestDirectory:(NSString *)testDirectory;
35 |
36 | - (void)startTestSession:(NSString *)clientSdk;
37 |
38 | - (void)resetTestLibrary;
39 |
40 | - (void)readResponse:(ATLHttpResponse *)httpResponse;
41 |
42 | - (void)addInfoToSend:(NSString *)key
43 | value:(NSString *)value;
44 |
45 | - (void)sendInfoToServer:(NSString *)basePath;
46 |
47 | - (void)signalEndWaitWithReason:(NSString *)reason;
48 |
49 | - (void)cancelTestAndGetNext;
50 |
51 | - (void)doNotExitAfterEnd;
52 |
53 | + (ATLTestLibrary *)testLibraryWithBaseUrl:(NSString *)baseUrl
54 | andControlUrl:(NSString *)controlUrl
55 | andCommandDelegate:(NSObject *)commandDelegate;
56 | @end
57 |
--------------------------------------------------------------------------------
/test/app/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CADisableMinimumFrameDurationOnPhone
6 |
7 | CFBundleDevelopmentRegion
8 | $(DEVELOPMENT_LANGUAGE)
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | app
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UIApplicationSupportsIndirectInputEvents
28 |
29 | UILaunchStoryboardName
30 | LaunchScreen
31 | UIMainStoryboardFile
32 | Main
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | UIViewControllerBasedStatusBarAppearance
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: "961ce3ec82ab88237be012c24eee24f9b10591dd"
8 | channel: "master"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
17 | base_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
18 | - platform: android
19 | create_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
20 | base_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
21 | - platform: ios
22 | create_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
23 | base_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
24 | - platform: linux
25 | create_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
26 | base_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
27 | - platform: macos
28 | create_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
29 | base_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
30 | - platform: web
31 | create_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
32 | base_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
33 | - platform: windows
34 | create_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
35 | base_revision: 961ce3ec82ab88237be012c24eee24f9b10591dd
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CADisableMinimumFrameDurationOnPhone
6 |
7 | CFBundleDevelopmentRegion
8 | $(DEVELOPMENT_LANGUAGE)
9 | CFBundleDisplayName
10 | AdjustExample
11 | CFBundleExecutable
12 | $(EXECUTABLE_NAME)
13 | CFBundleIdentifier
14 | $(PRODUCT_BUNDLE_IDENTIFIER)
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | AdjustExample
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | $(FLUTTER_BUILD_NAME)
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | $(FLUTTER_BUILD_NUMBER)
27 | LSRequiresIPhoneOS
28 |
29 | NSUserTrackingUsageDescription
30 | This is needed to access IDFA
31 | UIApplicationSupportsIndirectInputEvents
32 |
33 | UILaunchStoryboardName
34 | LaunchScreen
35 | UIMainStoryboardFile
36 | Main
37 | UISupportedInterfaceOrientations
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationLandscapeLeft
41 | UIInterfaceOrientationLandscapeRight
42 |
43 | UISupportedInterfaceOrientations~ipad
44 |
45 | UIInterfaceOrientationPortrait
46 | UIInterfaceOrientationPortraitUpsideDown
47 | UIInterfaceOrientationLandscapeLeft
48 | UIInterfaceOrientationLandscapeRight
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/test/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: test_lib
2 | description: Flutter plugin for Adjust Testing Library. Intended exclusively for internal use.
3 | version: 5.4.2
4 | author: Adjust (sdk@adjust.com)
5 |
6 | environment:
7 | sdk: ">=2.12.0 <3.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | meta: ">=1.1.6 <2.0.0"
13 |
14 | # For information on the generic Dart part of this file, see the
15 | # following page: https://www.dartlang.org/tools/pub/pubspec
16 |
17 | # The following section is specific to Flutter.
18 | flutter:
19 | plugin:
20 | androidPackage: com.adjust.test.lib
21 | pluginClass: TestLibPlugin
22 |
23 | # we don't want to publish the test lib plugin, used only privately for integration testing
24 | publish_to:
25 | none
26 |
27 | # To add assets to your plugin package, add an assets section, like this:
28 | # assets:
29 | # - images/a_dot_burr.jpeg
30 | # - images/a_dot_ham.jpeg
31 | #
32 | # For details regarding assets in packages, see
33 | # https://flutter.io/assets-and-images/#from-packages
34 | #
35 | # An image asset can refer to one or more resolution-specific "variants", see
36 | # https://flutter.io/assets-and-images/#resolution-aware.
37 |
38 | # To add custom fonts to your plugin package, add a fonts section here,
39 | # in this "flutter" section. Each entry in this list should have a
40 | # "family" key with the font family name, and a "fonts" key with a
41 | # list giving the asset and other descriptors for the font. For
42 | # example:
43 | # fonts:
44 | # - family: Schyler
45 | # fonts:
46 | # - asset: fonts/Schyler-Regular.ttf
47 | # - asset: fonts/Schyler-Italic.ttf
48 | # style: italic
49 | # - family: Trajan Pro
50 | # fonts:
51 | # - asset: fonts/TrajanPro.ttf
52 | # - asset: fonts/TrajanPro_Bold.ttf
53 | # weight: 700
54 | #
55 | # For details regarding fonts in packages, see
56 | # https://flutter.io/custom-fonts/#from-packages
57 |
--------------------------------------------------------------------------------
/lib/adjust_app_store_subscription.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_app_store_subscription.dart
3 | // Adjust SDK
4 | //
5 | // Created by Ugljesa Erceg (@uerceg) on 9th June 2020.
6 | // Copyright (c) 2020-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | import 'dart:convert';
10 |
11 | class AdjustAppStoreSubscription {
12 | final String _price;
13 | final String _currency;
14 | final String _transactionId;
15 | String? transactionDate;
16 | String? salesRegion;
17 | String? _billingStore;
18 | Map? _callbackParameters;
19 | Map? _partnerParameters;
20 |
21 | AdjustAppStoreSubscription(this._price, this._currency, this._transactionId) {
22 | _billingStore = "iOS";
23 | _callbackParameters = new Map();
24 | _partnerParameters = new Map();
25 | }
26 |
27 | void addCallbackParameter(String key, String value) {
28 | _callbackParameters![key] = value;
29 | }
30 |
31 | void addPartnerParameter(String key, String value) {
32 | _partnerParameters![key] = value;
33 | }
34 |
35 | Map get toMap {
36 | Map subscriptionMap = new Map();
37 |
38 | subscriptionMap['price'] = _price;
39 | subscriptionMap['currency'] = _currency;
40 | subscriptionMap['transactionId'] = _transactionId;
41 | if (transactionDate != null) {
42 | subscriptionMap['transactionDate'] = transactionDate;
43 | }
44 | if (salesRegion != null) {
45 | subscriptionMap['salesRegion'] = salesRegion;
46 | }
47 | if (_billingStore != null) {
48 | subscriptionMap['billingStore'] = _billingStore;
49 | }
50 | if (_callbackParameters!.length > 0) {
51 | subscriptionMap['callbackParameters'] = json.encode(_callbackParameters);
52 | }
53 | if (_partnerParameters!.length > 0) {
54 | subscriptionMap['partnerParameters'] = json.encode(_partnerParameters);
55 | }
56 |
57 | return subscriptionMap;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/lib/adjust_attribution.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_attribution.dart
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 25th April 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | class AdjustAttribution {
10 | final String? trackerToken;
11 | final String? trackerName;
12 | final String? network;
13 | final String? campaign;
14 | final String? adgroup;
15 | final String? creative;
16 | final String? clickLabel;
17 | final String? costType;
18 | final num? costAmount;
19 | final String? costCurrency;
20 | final String? jsonResponse;
21 | // android only
22 | final String? fbInstallReferrer;
23 |
24 | AdjustAttribution({
25 | this.trackerToken,
26 | this.trackerName,
27 | this.network,
28 | this.campaign,
29 | this.adgroup,
30 | this.creative,
31 | this.clickLabel,
32 | this.costType,
33 | this.costAmount,
34 | this.costCurrency,
35 | this.jsonResponse,
36 | this.fbInstallReferrer,
37 | });
38 |
39 | factory AdjustAttribution.fromMap(dynamic map) {
40 | try {
41 | double parsedCostAmount = -1;
42 | try {
43 | if (map['costAmount'] != null) {
44 | parsedCostAmount = double.parse(map['costAmount']);
45 | }
46 | } catch (ex) {}
47 |
48 | return AdjustAttribution(
49 | trackerToken: map['trackerToken'],
50 | trackerName: map['trackerName'],
51 | network: map['network'],
52 | campaign: map['campaign'],
53 | adgroup: map['adgroup'],
54 | creative: map['creative'],
55 | clickLabel: map['clickLabel'],
56 | costType: map['costType'],
57 | costAmount: parsedCostAmount != -1 ? parsedCostAmount : null,
58 | costCurrency: map['costCurrency'],
59 | jsonResponse: map['jsonResponse'],
60 | fbInstallReferrer: map['fbInstallReferrer'],
61 | );
62 | } catch (e) {
63 | throw Exception(
64 | '[AdjustFlutter]: Failed to create AdjustAttribution object from given map object. Details: ' +
65 | e.toString());
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/lib/adjust_play_store_subscription.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_play_store_subscription.dart
3 | // Adjust SDK
4 | //
5 | // Created by Ugljesa Erceg (@uerceg) on 9th June 2020.
6 | // Copyright (c) 2020-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | import 'dart:convert';
10 |
11 | class AdjustPlayStoreSubscription {
12 | final String _price;
13 | final String _currency;
14 | final String _sku;
15 | final String _orderId;
16 | final String _signature;
17 | final String _purchaseToken;
18 | String? _billingStore;
19 | String? purchaseTime;
20 | Map? _callbackParameters;
21 | Map? _partnerParameters;
22 |
23 | AdjustPlayStoreSubscription(
24 | this._price,
25 | this._currency,
26 | this._sku,
27 | this._orderId,
28 | this._signature,
29 | this._purchaseToken) {
30 | _billingStore = "GooglePlay";
31 | _callbackParameters = new Map();
32 | _partnerParameters = new Map();
33 | }
34 |
35 | void addCallbackParameter(String key, String value) {
36 | _callbackParameters![key] = value;
37 | }
38 |
39 | void addPartnerParameter(String key, String value) {
40 | _partnerParameters![key] = value;
41 | }
42 |
43 | Map get toMap {
44 | Map subscriptionMap = new Map();
45 |
46 | subscriptionMap['price'] = _price;
47 | subscriptionMap['currency'] = _currency;
48 | subscriptionMap['sku'] = _sku;
49 | subscriptionMap['orderId'] = _orderId;
50 | subscriptionMap['signature'] = _signature;
51 | subscriptionMap['purchaseToken'] = _purchaseToken;
52 | if (_billingStore != null) {
53 | subscriptionMap['billingStore'] = _billingStore;
54 | }
55 | if (purchaseTime != null) {
56 | subscriptionMap['purchaseTime'] = purchaseTime;
57 | }
58 | if (_callbackParameters!.length > 0) {
59 | subscriptionMap['callbackParameters'] = json.encode(_callbackParameters);
60 | }
61 | if (_partnerParameters!.length > 0) {
62 | subscriptionMap['partnerParameters'] = json.encode(_partnerParameters);
63 | }
64 |
65 | return subscriptionMap;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/lib/adjust_ad_revenue.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_ad_revenue.dart
3 | // Adjust SDK
4 | //
5 | // Created by Uglješa Erceg (@uerceg) on 10th June 2021.
6 | // Copyright (c) 2021-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | import 'dart:convert';
10 |
11 | class AdjustAdRevenue {
12 | final String _source;
13 | num? _revenue;
14 | String? _currency;
15 | num? adImpressionsCount;
16 | String? adRevenueNetwork;
17 | String? adRevenueUnit;
18 | String? adRevenuePlacement;
19 | Map? _callbackParameters;
20 | Map? _partnerParameters;
21 |
22 | AdjustAdRevenue(this._source) {
23 | _callbackParameters = new Map();
24 | _partnerParameters = new Map();
25 | }
26 |
27 | void setRevenue(num revenue, String currency) {
28 | _revenue = revenue;
29 | _currency = currency;
30 | }
31 |
32 | void addCallbackParameter(String key, String value) {
33 | _callbackParameters![key] = value;
34 | }
35 |
36 | void addPartnerParameter(String key, String value) {
37 | _partnerParameters![key] = value;
38 | }
39 |
40 | Map get toMap {
41 | Map adRevenueMap = {'source': _source};
42 |
43 | if (_revenue != null) {
44 | adRevenueMap['revenue'] = _revenue.toString();
45 | }
46 | if (_currency != null) {
47 | adRevenueMap['currency'] = _currency;
48 | }
49 | if (adImpressionsCount != null) {
50 | adRevenueMap['adImpressionsCount'] = adImpressionsCount.toString();
51 | }
52 | if (adRevenueNetwork != null) {
53 | adRevenueMap['adRevenueNetwork'] = adRevenueNetwork;
54 | }
55 | if (adRevenueUnit != null) {
56 | adRevenueMap['adRevenueUnit'] = adRevenueUnit;
57 | }
58 | if (adRevenuePlacement != null) {
59 | adRevenueMap['adRevenuePlacement'] = adRevenuePlacement;
60 | }
61 | if (_callbackParameters!.length > 0) {
62 | adRevenueMap['callbackParameters'] = json.encode(_callbackParameters);
63 | }
64 | if (_partnerParameters!.length > 0) {
65 | adRevenueMap['partnerParameters'] = json.encode(_partnerParameters);
66 | }
67 |
68 | return adRevenueMap;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/lib/adjust_event.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_event.dart
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 25th April 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | import 'dart:convert';
10 |
11 | class AdjustEvent {
12 | final String _eventToken;
13 | num? _revenue;
14 | String? _currency;
15 | String? callbackId;
16 | String? deduplicationId;
17 | String? productId;
18 | Map? _callbackParameters;
19 | Map? _partnerParameters;
20 | // ios only
21 | String? transactionId;
22 | // android only
23 | String? purchaseToken;
24 |
25 | AdjustEvent(this._eventToken) {
26 | _callbackParameters = new Map();
27 | _partnerParameters = new Map();
28 | }
29 |
30 | void setRevenue(num revenue, String currency) {
31 | _revenue = revenue;
32 | _currency = currency;
33 | }
34 |
35 | void addCallbackParameter(String key, String value) {
36 | _callbackParameters![key] = value;
37 | }
38 |
39 | void addPartnerParameter(String key, String value) {
40 | _partnerParameters![key] = value;
41 | }
42 |
43 | Map get toMap {
44 | Map eventMap = {'eventToken': _eventToken};
45 |
46 | if (_revenue != null) {
47 | eventMap['revenue'] = _revenue.toString();
48 | }
49 | if (_currency != null) {
50 | eventMap['currency'] = _currency;
51 | }
52 | if (deduplicationId != null) {
53 | eventMap['deduplicationId'] = deduplicationId;
54 | }
55 | if (transactionId != null) {
56 | eventMap['transactionId'] = transactionId;
57 | }
58 | if (productId != null) {
59 | eventMap['productId'] = productId;
60 | }
61 | if (purchaseToken != null) {
62 | eventMap['purchaseToken'] = purchaseToken;
63 | }
64 | if (callbackId != null) {
65 | eventMap['callbackId'] = callbackId;
66 | }
67 | if (_callbackParameters!.length > 0) {
68 | eventMap['callbackParameters'] = json.encode(_callbackParameters);
69 | }
70 | if (_partnerParameters!.length > 0) {
71 | eventMap['partnerParameters'] = json.encode(_partnerParameters);
72 | }
73 |
74 | return eventMap;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
33 |
34 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/test/app/lib/command.dart:
--------------------------------------------------------------------------------
1 | //
2 | // command.dart
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 25th April 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | import 'dart:convert';
10 | import 'dart:io';
11 |
12 | /// represents a test command received from the test library
13 | /// contains class name, method name, and parameters for execution
14 | class Command {
15 | String? _className;
16 | String? _methodName;
17 | String? _jsonParameters;
18 | Map? _parameters;
19 |
20 | /// creates a Command from a dynamic map received from the test framework
21 | Command(dynamic map) {
22 | try {
23 | _className = map['className'];
24 | _methodName = map['methodName'];
25 |
26 | if (Platform.isAndroid) {
27 | // android sends parameters as JSON string
28 | _jsonParameters = map['jsonParameters'];
29 | _parameters = json.decode(_jsonParameters!);
30 | } else {
31 | // iOS sends parameters as map directly
32 | _parameters = map['jsonParameters'];
33 | _jsonParameters = json.encode(_parameters);
34 | }
35 | } catch (e) {
36 | print('[Command]: Failed to parse command from incoming data. Error: $e');
37 | }
38 | }
39 |
40 | /// the class name to execute the method on
41 | String? get className => _className;
42 |
43 | /// the method name to execute
44 | String? get methodName => _methodName;
45 |
46 | /// gets the first value for a given parameter key
47 | /// returns null if parameter doesn't exist or has no values
48 | String? getFirstParameterValue(String parameterKey) {
49 | final List? parameterValues = _parameters![parameterKey];
50 | if (parameterValues == null || parameterValues.isEmpty) {
51 | return null;
52 | }
53 | return parameterValues.first;
54 | }
55 |
56 | /// gets all parameter values for a given key
57 | /// fixed typo: was "getParamteters", now "getParameters"
58 | List? getParameters(String parameterKey) {
59 | return _parameters![parameterKey];
60 | }
61 |
62 | /// checks if the command contains a specific parameter
63 | bool containsParameter(String parameterKey) {
64 | return _parameters?[parameterKey] != null;
65 | }
66 |
67 | /// returns a string representation of the command for debugging
68 | @override
69 | String toString() {
70 | return 'Command[className: $_className, methodName: $_methodName, jsonParameters: $_jsonParameters]';
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test/app/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test/app/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
18 |
22 |
26 |
31 |
35 |
36 |
37 |
38 |
39 |
40 |
42 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/test/app/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/test/lib/test_lib.dart:
--------------------------------------------------------------------------------
1 | //
2 | // test_lib.dart
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 25th April 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | import 'package:flutter/services.dart';
10 |
11 | typedef void ExecuteCommandHandler(final dynamic callArgs);
12 |
13 | class TestLib {
14 | static const MethodChannel _channel =
15 | const MethodChannel('com.adjust.test.lib/api');
16 | static ExecuteCommandHandler? _executeCommandHandler;
17 |
18 | static void setExecuteCommandHalder(ExecuteCommandHandler handler) {
19 | _executeCommandHandler = handler;
20 | _channel.setMethodCallHandler((MethodCall call) async {
21 | try {
22 | switch (call.method) {
23 | case 'adj-test-execute':
24 | if (_executeCommandHandler != null) {
25 | _executeCommandHandler!(call.arguments);
26 | }
27 | break;
28 | default:
29 | throw new UnsupportedError(
30 | '[TestLibrary]: Received unknown native method: ${call.method}');
31 | }
32 | } catch (e) {
33 | print(e.toString());
34 | }
35 | });
36 | }
37 |
38 | static void init(String baseUrl, String controlUrl) {
39 | _channel
40 | .invokeMethod('init', {'baseUrl': baseUrl, 'controlUrl': controlUrl});
41 | }
42 |
43 | static void startTestSession(String clientSdk) {
44 | _channel.invokeMethod('startTestSession', {'clientSdk': clientSdk});
45 | }
46 |
47 | static void addInfoToSend(String key, String? value) {
48 | if (value == null) {
49 | print(
50 | '[TestLibrary]: Skip adding info to server for key [$key]. Value is null.');
51 | return;
52 | }
53 | _channel.invokeMethod('addInfoToSend', {'key': key, 'value': value});
54 | }
55 |
56 | static void sendInfoToServer(String? basePath) {
57 | if (basePath == null) {
58 | print(
59 | '[TestLibrary]: Skip sending info to server with base path set to null.');
60 | return;
61 | }
62 | _channel.invokeMethod('sendInfoToServer', {'basePath': basePath});
63 | }
64 |
65 | static void addTest(String? testName) {
66 | if (testName == null) {
67 | print('[TestLibrary]: Skip adding test with null value for the name.');
68 | return;
69 | }
70 | _channel.invokeMethod('addTest', {'testName': testName});
71 | }
72 |
73 | static void addTestDirectory(String? testDirectory) {
74 | if (testDirectory == null) {
75 | print(
76 | '[TestLibrary]: Skip adding test directory with null value for the name.');
77 | return;
78 | }
79 | _channel.invokeMethod('addTestDirectory', {'testDirectory': testDirectory});
80 | }
81 |
82 | static void doNotExitAfterEnd() {
83 | _channel.invokeMethod('doNotExitAfterEnd');
84 | }
85 |
86 | static void setTestConnectionOptions() {
87 | _channel.invokeMethod('setTestConnectionOptions');
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # Adjust Flutter Example App
2 |
3 | A comprehensive demonstration application showcasing the full functionality of the Adjust Flutter SDK. This app provides interactive examples of all major SDK features and serves as a reference implementation.
4 |
5 | ## Features
6 |
7 | - **Event Tracking**: Demonstrate simple, revenue, callback, and partner events
8 | - **Device Information**: Access Google AdID, Adjust identifier, IDFA, and attribution data
9 | - **SDK Management**: Toggle SDK state and check enabled status
10 | - **Real-time Callbacks**: Live demonstration of attribution, session, and event callbacks
11 | - **Modern UI**: Beautiful, intuitive interface following Adjust design guidelines
12 |
13 | ## Getting Started
14 |
15 | 1. **Prerequisites**: Ensure Flutter is installed and configured
16 | 2. **Install Dependencies**: Run `flutter pub get` in this directory
17 | 3. **Run the App**: Use `flutter run` to start the example application
18 | 4. **Explore Features**: Tap buttons to test different SDK functionalities
19 |
20 | ## App Structure
21 |
22 | - **Event Tracking Section**: Test different types of events with various parameters
23 | - **Device Information Section**: Retrieve device-specific identifiers and attribution
24 | - **SDK Control Section**: Manage SDK state and verify functionality
25 |
26 | ## SDK Configuration
27 |
28 | The app is configured with:
29 | - **App Token**: `2fm9gkqubvpc` (sandbox environment)
30 | - **Environment**: Sandbox mode for safe testing
31 | - **Log Level**: Verbose logging for detailed insights
32 | - **Callbacks**: Comprehensive callback setup for all event types
33 |
34 | ## Event Tokens
35 |
36 | The following test event tokens are configured:
37 | - **Simple Event**: `g3mfiw` - Basic event tracking
38 | - **Revenue Event**: `a4fd35` - Event with revenue data
39 | - **Callback Event**: `34vgg9` - Event with callback parameters
40 | - **Partner Event**: `w788qs` - Event with partner parameters
41 |
42 | ## Usage Examples
43 |
44 | ### Track a Simple Event
45 | ```dart
46 | final event = AdjustEvent('g3mfiw');
47 | Adjust.trackEvent(event);
48 | ```
49 |
50 | ### Track Revenue Event
51 | ```dart
52 | final event = AdjustEvent('a4fd35');
53 | event.setRevenue(100.0, 'EUR');
54 | event.transactionId = 'DummyTransactionId';
55 | Adjust.trackEvent(event);
56 | ```
57 |
58 | ### Get Attribution Data
59 | ```dart
60 | Adjust.getAttribution().then((attribution) {
61 | // Handle attribution data
62 | });
63 | ```
64 |
65 | ## Callbacks
66 |
67 | The app demonstrates all available callback types:
68 | - **Attribution Callback**: Triggered when attribution data changes
69 | - **Session Success/Failure**: Monitor session tracking status
70 | - **Event Success/Failure**: Track event delivery status
71 | - **Deferred Deeplinks**: Handle deferred deeplink scenarios
72 | - **SKAN Updates**: iOS StoreKit Ad Network updates
73 |
74 | ## Testing
75 |
76 | Use this app to:
77 | - Verify SDK integration in your development environment
78 | - Test different event tracking scenarios
79 | - Understand callback behavior and data structure
80 | - Validate attribution and device identifier retrieval
81 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/test/app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/test/app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
38 |
39 |
40 |
41 |
42 |
43 |
55 |
57 |
63 |
64 |
65 |
66 |
72 |
74 |
80 |
81 |
82 |
83 |
85 |
86 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
38 |
39 |
40 |
41 |
44 |
50 |
51 |
52 |
53 |
54 |
66 |
68 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # =============================================
2 | # ADJUST FLUTTER SDK - COMPREHENSIVE .GITIGNORE
3 | # =============================================
4 | # This file handles all ignore patterns for the entire project.
5 | # Organized by category for easy maintenance.
6 |
7 | # =====================
8 | # SYSTEM & EDITOR FILES
9 | # =====================
10 | # miscellaneous system files
11 | *.class
12 | *.lock
13 | *.log
14 | *.pyc
15 | *.swp
16 | .DS_Store
17 | .atom/
18 | .build/
19 | .buildlog/
20 | .history
21 | .svn/
22 | .swiftpm/
23 | migrate_working_dir/
24 |
25 | # intellij related
26 | *.iml
27 | *.ipr
28 | *.iws
29 | .idea/
30 |
31 | # visual studio code related
32 | .classpath
33 | .project
34 | .settings/
35 | .vscode/
36 |
37 | # ==============
38 | # FLUTTER & DART
39 | # ==============
40 | # flutter/dart/pub related
41 | **/doc/api/
42 | **/ios/Flutter/.last_build_id
43 | .dart_tool/
44 | .flutter-plugins
45 | .flutter-plugins-dependencies
46 | **/generated_plugin_registrant.dart
47 | .packages
48 | .packages.generated
49 | .pub-cache/
50 | .pub/
51 | build/
52 | coverage/
53 | flutter_*.png
54 | linked_*.ds
55 | unlinked.ds
56 | unlinked_spec.ds
57 |
58 | # ====================
59 | # ANDROID BUILD SYSTEM
60 | # ====================
61 | # android build artifacts
62 | **/android/.gradle
63 | **/android/captures/
64 | **/android/local.properties
65 | **/android/**/GeneratedPluginRegistrant.java
66 | **/android/key.properties
67 | **/android/app/debug
68 | **/android/app/profile
69 | **/android/app/release
70 | *.jks
71 | *.keystore
72 |
73 | # android studio will place build artifacts here
74 | /android/app/debug
75 | /android/app/profile
76 | /android/app/release
77 |
78 | # =================
79 | # IOS BUILD SYSTEM
80 | # =================
81 | # ios/xcode related
82 | **/ios/**/*.mode1v3
83 | **/ios/**/*.mode2v3
84 | **/ios/**/*.moved-aside
85 | **/ios/**/*.pbxuser
86 | **/ios/**/*.perspectivev3
87 | **/ios/**/*sync/
88 | **/ios/**/.sconsign.dblite
89 | **/ios/**/.tags*
90 | **/ios/**/.vagrant/
91 | **/ios/**/DerivedData/
92 | **/ios/**/Icon?
93 | **/ios/**/Pods/
94 | **/ios/**/.symlinks/
95 | **/ios/Podfile.lock
96 | **/ios/**/profile
97 | **/ios/**/xcuserdata
98 | **/ios/.generated/
99 | **/ios/Flutter/App.framework
100 | **/ios/Flutter/Flutter.framework
101 | **/ios/Flutter/Flutter.podspec
102 | **/ios/Flutter/Generated.xcconfig
103 | **/ios/Flutter/ephemeral
104 | **/ios/Flutter/app.flx
105 | **/ios/Flutter/app.zip
106 | **/ios/Flutter/flutter_assets/
107 | **/ios/Flutter/flutter_export_environment.sh
108 | **/ios/ServiceDefinitions.json
109 | **/ios/Runner/GeneratedPluginRegistrant.*
110 | **/ios/**/dgph
111 |
112 | # macos
113 | **/macos/Flutter/GeneratedPluginRegistrant.swift
114 |
115 | # ====================
116 | # FLUTTER SDK SPECIFIC
117 | # ====================
118 | # flutter repo-specific (for SDK development)
119 | /bin/cache/
120 | /bin/internal/bootstrap.bat
121 | /bin/internal/bootstrap.sh
122 | /bin/mingit/
123 | /dev/benchmarks/mega_gallery/
124 | /dev/bots/.recipe_deps
125 | /dev/bots/android_tools/
126 | /dev/devicelab/ABresults*.json
127 | /dev/docs/doc/
128 | /dev/docs/flutter.docs.zip
129 | /dev/docs/lib/
130 | /dev/docs/pubspec.yaml
131 | /dev/integration_tests/**/xcuserdata
132 | /dev/integration_tests/**/Pods
133 | /packages/flutter/coverage/
134 | version
135 | analysis_benchmark.json
136 |
137 | # =========================
138 | # BUILD ARTIFACTS & SYMBOLS
139 | # =========================
140 | # symbolication related
141 | app.*.symbols
142 |
143 | # obfuscation related
144 | app.*.map.json
145 |
146 | # =======================================
147 | # EXCEPTIONS - FILES THAT MUST BE TRACKED
148 | # =======================================
149 | # these files are essential for building the apps after cloning
150 |
151 | # allow default ios files
152 | !**/ios/**/default.mode1v3
153 | !**/ios/**/default.mode2v3
154 | !**/ios/**/default.pbxuser
155 | !**/ios/**/default.perspectivev3
156 |
157 | # allow essential flutter tools test data
158 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
159 | !/dev/ci/**/Gemfile.lock
160 |
161 | # allow gradle build system files for example and test apps
162 | # these are essential for building without local gradle installation
163 | !example/android/gradlew
164 | !example/android/gradlew.bat
165 | !example/android/gradle/wrapper/gradle-wrapper.jar
166 | !test/app/android/gradlew
167 | !test/app/android/gradlew.bat
168 | !test/app/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/example/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/test/app/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/test/ios/Classes/TestLibPlugin.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestLibPlugin.m
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 1st October 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | #import "TestLibPlugin.h"
10 | #import "AdjustCommandExecutor.h"
11 |
12 | @interface TestLibPlugin ()
13 |
14 | @property(nonatomic, retain) FlutterMethodChannel *channel;
15 | @property(nonatomic, strong) ATLTestLibrary *testLibrary;
16 | @property(nonatomic, strong) AdjustCommandExecutor *adjustCommandExecutor;
17 |
18 | @end
19 |
20 | @implementation TestLibPlugin
21 |
22 | + (void)registerWithRegistrar:(NSObject *)registrar {
23 | FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"com.adjust.test.lib/api"
24 | binaryMessenger:[registrar messenger]];
25 | TestLibPlugin *instance = [[TestLibPlugin alloc] init];
26 | instance.channel = channel;
27 | [registrar addMethodCallDelegate:instance channel:channel];
28 | }
29 |
30 | // TODO: check if needed
31 | - (void)dealloc {
32 | [self.channel setMethodCallHandler:nil];
33 | self.channel = nil;
34 | }
35 |
36 | - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
37 | if ([@"init" isEqualToString:call.method]) {
38 | [self init:call withResult:result];
39 | } else if ([@"startTestSession" isEqualToString:call.method]) {
40 | [self startTestSession:call withResult:result];
41 | } else if ([@"addInfoToSend" isEqualToString:call.method]) {
42 | [self addInfoToSend:call withResult:result];
43 | } else if ([@"sendInfoToServer" isEqualToString:call.method]) {
44 | [self sendInfoToServer:call withResult:result];
45 | } else if ([@"addTest" isEqualToString:call.method]) {
46 | [self addTest:call withResult:result];
47 | } else if ([@"addTestDirectory" isEqualToString:call.method]) {
48 | [self addTestDirectory:call withResult:result];
49 | } else if ([@"doNotExitAfterEnd" isEqualToString:call.method]) {
50 | [self doNotExitAfterEnd:call withResult:result];
51 | } else if ([@"setTestConnectionOptions" isEqualToString:call.method]) {
52 | // do nothing, Android specific method
53 | } else {
54 | result(FlutterMethodNotImplemented);
55 | }
56 | }
57 |
58 | - (void)init:(FlutterMethodCall *)call withResult:(FlutterResult)result {
59 | NSLog(@"Initializing test lib bridge ...");
60 | NSString *baseUrl = call.arguments[@"baseUrl"];
61 | NSString *controlUrl = call.arguments[@"controlUrl"];
62 | if (![self isFieldValid:baseUrl] || ![self isFieldValid:controlUrl]) {
63 | result([FlutterError errorWithCode:@"WRONG-ARGS"
64 | message:@"Arguments null or wrong (missing argument >baseUrl< or >controlUrl<)"
65 | details:nil]);
66 | return;
67 | }
68 |
69 | self.adjustCommandExecutor = [[AdjustCommandExecutor alloc]initWithMethodChannel:self.channel];
70 | self.testLibrary = [ATLTestLibrary testLibraryWithBaseUrl:baseUrl andControlUrl:controlUrl andCommandDelegate:self.adjustCommandExecutor];
71 | NSLog(@"TestLib bridge initialized.");
72 | }
73 |
74 | - (void)startTestSession:(FlutterMethodCall *)call withResult:(FlutterResult)result {
75 | if ([self testLibOk:result] == NO) {
76 | NSLog(@"Error. Cannot start test session. Test lib bridge not initialized.");
77 | return;
78 | }
79 |
80 | NSString *clientSdk = call.arguments[@"clientSdk"];
81 | if (![self isFieldValid:clientSdk]) {
82 | result([FlutterError errorWithCode:@"WRONG-CLIENT-SDK"
83 | message:@"Arguments null or wrong (missing argument >clientSdk<"
84 | details:nil]);
85 | return;
86 | }
87 |
88 | NSLog(@"Starting test session. Client SDK %@", clientSdk);
89 | [self.testLibrary startTestSession:clientSdk];
90 | }
91 |
92 | - (void)addInfoToSend:(FlutterMethodCall *)call withResult:(FlutterResult)result {
93 | if ([self testLibOk:result] == NO) {
94 | return;
95 | }
96 | NSString *key = call.arguments[@"key"];
97 | NSString *value = call.arguments[@"value"];
98 | [self.testLibrary addInfoToSend:key value:value];
99 | }
100 |
101 | - (void)sendInfoToServer:(FlutterMethodCall *)call withResult:(FlutterResult)result {
102 | if ([self testLibOk:result] == NO) {
103 | return;
104 | }
105 | NSString *basePath = call.arguments[@"basePath"];
106 | [self.testLibrary sendInfoToServer:basePath];
107 | }
108 |
109 | - (void)addTest:(FlutterMethodCall *)call withResult:(FlutterResult)result {
110 | if ([self testLibOk:result] == NO) {
111 | return;
112 | }
113 | NSString *testName = call.arguments[@"testName"];
114 | [self.testLibrary addTest:testName];
115 | }
116 |
117 | - (void)addTestDirectory:(FlutterMethodCall *)call withResult:(FlutterResult)result {
118 | if ([self testLibOk:result] == NO) {
119 | return;
120 | }
121 | NSString *testDirectory = call.arguments[@"testDirectory"];
122 | [self.testLibrary addTestDirectory:testDirectory];
123 | }
124 |
125 | - (void)doNotExitAfterEnd:(FlutterMethodCall *)call withResult:(FlutterResult)result {
126 | if ([self testLibOk:result] == NO) {
127 | return;
128 | }
129 | [self.testLibrary doNotExitAfterEnd];
130 | }
131 |
132 | // Helper methods
133 |
134 | - (BOOL)testLibOk:(FlutterResult)result {
135 | if (self.testLibrary == nil) {
136 | result([FlutterError errorWithCode:@"TEST-LIB-NIL"
137 | message:@"Test Library not initialized. Call >init< first."
138 | details:nil]);
139 | return NO;
140 | }
141 | return YES;
142 | }
143 |
144 | - (BOOL)isFieldValid:(NSObject *)field {
145 | if (field == nil) {
146 | return NO;
147 | }
148 |
149 | // Check if its an instance of the singleton NSNull
150 | if ([field isKindOfClass:[NSNull class]]) {
151 | return NO;
152 | }
153 |
154 | // If field can be converted to a string, check if it has any content.
155 | NSString *str = [NSString stringWithFormat:@"%@", field];
156 | if (str != nil) {
157 | if ([str length] == 0) {
158 | return NO;
159 | }
160 | }
161 |
162 | return YES;
163 | }
164 |
165 | @end
166 |
--------------------------------------------------------------------------------
/test/android/src/main/java/com/adjust/test/lib/TestLibPlugin.java:
--------------------------------------------------------------------------------
1 | //
2 | // TestLibPlugin.java
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 1st October 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | package com.adjust.test.lib;
10 |
11 | import android.content.Context;
12 | import android.os.Handler;
13 | import android.os.Looper;
14 | import android.util.Log;
15 |
16 | import androidx.annotation.NonNull;
17 |
18 | import io.flutter.embedding.engine.plugins.FlutterPlugin;
19 | import io.flutter.plugin.common.MethodCall;
20 | import io.flutter.plugin.common.MethodChannel;
21 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
22 | import io.flutter.plugin.common.MethodChannel.Result;
23 |
24 | import com.adjust.test.ICommandJsonListener;
25 | import com.adjust.test.TestLibrary;
26 | import com.adjust.test_options.TestConnectionOptions;
27 |
28 | import java.util.HashMap;
29 | import java.util.Map;
30 |
31 | public class TestLibPlugin implements FlutterPlugin, MethodCallHandler {
32 | private static String TAG = "TestLibPlugin";
33 | private TestLibrary testLibrary = null;
34 | private MethodChannel channel;
35 | private Context applicationContext;
36 |
37 | public TestLibPlugin() {}
38 |
39 | @Override
40 | public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
41 | applicationContext = binding.getApplicationContext();
42 | channel = new MethodChannel(binding.getBinaryMessenger(), "com.adjust.test.lib/api");
43 | channel.setMethodCallHandler(this);
44 | }
45 |
46 | @Override
47 | public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
48 | applicationContext = null;
49 | if (channel != null) {
50 | channel.setMethodCallHandler(null);
51 | }
52 | channel = null;
53 | }
54 |
55 | @Override
56 | public void onMethodCall(MethodCall call, Result result) {
57 | switch (call.method) {
58 | case "init":
59 | init(call, result);
60 | break;
61 | case "startTestSession":
62 | startTestSession(call, result);
63 | break;
64 | case "addInfoToSend":
65 | addInfoToSend(call, result);
66 | break;
67 | case "sendInfoToServer":
68 | sendInfoToServer(call, result);
69 | break;
70 | case "addTest":
71 | addTest(call, result);
72 | break;
73 | case "addTestDirectory":
74 | addTestDirectory(call, result);
75 | break;
76 | case "doNotExitAfterEnd":
77 | doNotExitAfterEnd(result);
78 | break;
79 | case "setTestConnectionOptions":
80 | setTestConnectionOptions(result);
81 | break;
82 | default:
83 | error("Not implemented method: " + call.method);
84 | result.notImplemented();
85 | break;
86 | }
87 | }
88 |
89 | private void init(final MethodCall call, final Result result) {
90 | Map paramsMap = (Map)call.arguments;
91 | if (!paramsMap.containsKey("baseUrl") || !paramsMap.containsKey("controlUrl")) {
92 | result.error("0", "Arguments null or wrong (missing 'baseUrl' or 'controlUrl')", null);
93 | return;
94 | }
95 |
96 | String baseUrl = (String) paramsMap.get("baseUrl");
97 | String controlUrl = (String) paramsMap.get("controlUrl");
98 | final String dartMethodName = "adj-test-execute";
99 | testLibrary = new TestLibrary(baseUrl, controlUrl, applicationContext, new ICommandJsonListener() {
100 | @Override
101 | public void executeCommand(String className, String methodName, String jsonParameters) {
102 | final HashMap methodParams = new HashMap();
103 | methodParams.put("className", className);
104 | methodParams.put("methodName", methodName);
105 | methodParams.put("jsonParameters", jsonParameters);
106 |
107 | log("Trying to call a method 'adj-test-execute' with: " + className + "." + methodName);
108 | Handler mainHandler = new Handler(Looper.getMainLooper());
109 | Runnable myRunnable = new Runnable() {
110 | @Override
111 | public void run() {
112 | channel.invokeMethod(dartMethodName, methodParams);
113 | }
114 | };
115 | mainHandler.post(myRunnable);
116 | }
117 | });
118 | result.success(null);
119 | }
120 |
121 | private void startTestSession(final MethodCall call, final Result result) {
122 | if (testLibrary == null) {
123 | result.error("0", "Test Library not initialized. Call 'init' method first.", null);
124 | return;
125 | }
126 |
127 | Map paramsMap = (Map)call.arguments;
128 | if (!paramsMap.containsKey("clientSdk")) {
129 | result.error("0", "Arguments null or wrong (missing argument 'clientSdk'", null);
130 | return;
131 | }
132 |
133 | String clientSdk = (String) paramsMap.get("clientSdk");
134 | testLibrary.startTestSession(clientSdk);
135 | result.success(null);
136 | }
137 |
138 | private void addInfoToSend(final MethodCall call, final Result result) {
139 | if (testLibrary == null) {
140 | result.error("0", "Test Library not initialized. Call 'init' method first.", null);
141 | return;
142 | }
143 |
144 | Map paramsMap = (Map)call.arguments;
145 | String key = (String) paramsMap.get("key");
146 | String value = (String) paramsMap.get("value");
147 | testLibrary.addInfoToSend(key, value);
148 | result.success(null);
149 | }
150 |
151 | private void sendInfoToServer(final MethodCall call, final Result result) {
152 | if (testLibrary == null) {
153 | result.error("0", "Test Library not initialized. Call 'init' method first.", null);
154 | return;
155 | }
156 |
157 | Map paramsMap = (Map)call.arguments;
158 | String basePath = (String) paramsMap.get("basePath");
159 | testLibrary.sendInfoToServer(basePath);
160 | result.success(null);
161 | }
162 |
163 | private void addTest(final MethodCall call, final Result result) {
164 | if (testLibrary == null) {
165 | result.error("0", "Test Library not initialized. Call 'init' method first.", null);
166 | return;
167 | }
168 |
169 | Map paramsMap = (Map)call.arguments;
170 | String testName = (String) paramsMap.get("testName");
171 | assert testName != null;
172 | testLibrary.addTest(testName);
173 | result.success(null);
174 | }
175 |
176 | private void addTestDirectory(final MethodCall call, final Result result) {
177 | if (testLibrary == null) {
178 | result.error("0", "Test Library not initialized. Call 'init' method first.", null);
179 | return;
180 | }
181 |
182 | Map paramsMap = (Map)call.arguments;
183 | String testDirectory = (String) paramsMap.get("testDirectory");
184 | assert testDirectory != null;
185 | testLibrary.addTestDirectory(testDirectory);
186 | result.success(null);
187 | }
188 |
189 | private void doNotExitAfterEnd(final Result result) {
190 | if (testLibrary == null) {
191 | result.error("0", "Test Library not initialized. Call 'init' method first.", null);
192 | return;
193 | }
194 |
195 | testLibrary.doNotExitAfterEnd();
196 | result.success(null);
197 | }
198 |
199 | private void setTestConnectionOptions(final Result result) {
200 | if (testLibrary == null) {
201 | result.error("0", "Test Library not initialized. Call 'init' method first.", null);
202 | return;
203 | }
204 |
205 | TestConnectionOptions.setTestConnectionOptions();
206 | result.success(null);
207 | }
208 |
209 | private void log(String message) {
210 | Log.d(TAG, message);
211 | }
212 |
213 | private void error(String message) {
214 | Log.e(TAG, message);
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/test/app/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:adjust_sdk/adjust.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:test_app/command.dart';
6 | import 'package:test_app/command_executor.dart';
7 | import 'package:test_lib/test_lib.dart';
8 |
9 | void main() {
10 | runApp(const AdjustTestApp());
11 | }
12 |
13 | /// main application widget for Adjust Flutter Test App
14 | class AdjustTestApp extends StatelessWidget {
15 | const AdjustTestApp({super.key});
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return MaterialApp(
20 | title: 'Adjust Test App',
21 | debugShowCheckedModeBanner: false,
22 | theme: ThemeData(
23 | primarySwatch: Colors.blue,
24 | visualDensity: VisualDensity.adaptivePlatformDensity,
25 | useMaterial3: true,
26 | ),
27 | home: const TestHomePage(),
28 | );
29 | }
30 | }
31 |
32 | /// home page containing the test session controls
33 | class TestHomePage extends StatefulWidget {
34 | const TestHomePage({super.key});
35 |
36 | @override
37 | State createState() => _TestHomePageState();
38 | }
39 |
40 | class _TestHomePageState extends State {
41 | // configuration constants
42 | static const String _defaultAddress = '192.168.86.241';
43 | static const String _androidProtocol = 'https';
44 | static const String _androidPort = '8443';
45 | static const String _iosProtocol = 'http';
46 | static const String _iosPort = '8080';
47 | static const String _wsPort = '1987';
48 |
49 | // adjust brand colors
50 | static const Color _adjustNavy = Color(0xFF1B2951);
51 | static const Color _adjustNavyLight = Color(0xFF2A3A5C);
52 |
53 | String? _overwriteUrl;
54 | late String _controlUrl;
55 | late CommandExecutor _commandExecutor;
56 |
57 | @override
58 | void initState() {
59 | super.initState();
60 | _initializeTestEnvironment();
61 | }
62 |
63 | /// initialize the test environment with platform-specific URLs
64 | void _initializeTestEnvironment() {
65 | if (Platform.isAndroid) {
66 | _overwriteUrl = '$_androidProtocol://$_defaultAddress:$_androidPort';
67 | } else {
68 | _overwriteUrl = '$_iosProtocol://$_defaultAddress:$_iosPort';
69 | }
70 | _controlUrl = 'ws://$_defaultAddress:$_wsPort';
71 |
72 | // initialize command executor
73 | _commandExecutor = CommandExecutor(_overwriteUrl);
74 |
75 | // initialize test library with command handler
76 | TestLib.setExecuteCommandHalder(_handleTestCommand);
77 | TestLib.init(_overwriteUrl!, _controlUrl);
78 | }
79 |
80 | /// handle incoming test commands
81 | void _handleTestCommand(dynamic callArgs) {
82 | print('[AdjustTestApp]: Command handler triggered');
83 | final command = Command(callArgs);
84 | print('[AdjustTestApp]: Executing ${command.className}.${command.methodName}');
85 | _commandExecutor.executeCommand(command);
86 | }
87 |
88 | /// start a new test session
89 | void _startTestSession() {
90 | Adjust.getSdkVersion().then((sdkVersion) {
91 | print('[AdjustTestApp]: Starting test session with SDK version: $sdkVersion');
92 | // TestLib.addTestDirectory("getters");
93 | TestLib.startTestSession(sdkVersion);
94 | });
95 | }
96 |
97 | @override
98 | Widget build(BuildContext context) {
99 | return Scaffold(
100 | appBar: AppBar(
101 | title: const Text(
102 | 'Adjust Test App',
103 | style: TextStyle(
104 | fontWeight: FontWeight.w600,
105 | color: Colors.white,
106 | ),
107 | ),
108 | centerTitle: true,
109 | backgroundColor: _adjustNavy,
110 | elevation: 0,
111 | ),
112 | body: Container(
113 | width: double.infinity,
114 | height: double.infinity,
115 | decoration: const BoxDecoration(
116 | gradient: LinearGradient(
117 | begin: Alignment.topCenter,
118 | end: Alignment.bottomCenter,
119 | colors: [_adjustNavy, _adjustNavyLight],
120 | ),
121 | ),
122 | child: SafeArea(
123 | child: Padding(
124 | padding: const EdgeInsets.all(24.0),
125 | child: Column(
126 | mainAxisAlignment: MainAxisAlignment.center,
127 | children: [
128 | // app icon or logo space
129 | Container(
130 | width: 80,
131 | height: 80,
132 | decoration: BoxDecoration(
133 | color: Colors.white.withOpacity(0.1),
134 | borderRadius: BorderRadius.circular(16),
135 | ),
136 | child: const Icon(
137 | Icons.science_outlined,
138 | size: 40,
139 | color: Colors.white,
140 | ),
141 | ),
142 | const SizedBox(height: 32),
143 |
144 | // title and description
145 | const Text(
146 | 'Test Session',
147 | style: TextStyle(
148 | fontSize: 28,
149 | fontWeight: FontWeight.bold,
150 | color: Colors.white,
151 | ),
152 | ),
153 | const SizedBox(height: 8),
154 | Text(
155 | 'Tap the button below to start testing\nthe Adjust SDK functionality',
156 | textAlign: TextAlign.center,
157 | style: TextStyle(
158 | fontSize: 16,
159 | color: Colors.white.withOpacity(0.8),
160 | height: 1.4,
161 | ),
162 | ),
163 | const SizedBox(height: 48),
164 |
165 | // main action button
166 | _buildStartButton(),
167 |
168 | const SizedBox(height: 24),
169 |
170 | // connection info
171 | _buildConnectionInfo(),
172 | ],
173 | ),
174 | ),
175 | ),
176 | ),
177 | );
178 | }
179 |
180 | /// build the main start test session button
181 | Widget _buildStartButton() {
182 | return SizedBox(
183 | width: double.infinity,
184 | height: 56,
185 | child: ElevatedButton(
186 | onPressed: _startTestSession,
187 | style: ElevatedButton.styleFrom(
188 | backgroundColor: Colors.white,
189 | foregroundColor: _adjustNavy,
190 | shape: RoundedRectangleBorder(
191 | borderRadius: BorderRadius.circular(28),
192 | ),
193 | elevation: 8,
194 | shadowColor: Colors.black.withOpacity(0.3),
195 | ),
196 | child: const Row(
197 | mainAxisAlignment: MainAxisAlignment.center,
198 | children: [
199 | Icon(Icons.play_arrow_rounded, size: 24),
200 | SizedBox(width: 8),
201 | Text(
202 | 'Start Test Session',
203 | style: TextStyle(
204 | fontSize: 18,
205 | fontWeight: FontWeight.w600,
206 | ),
207 | ),
208 | ],
209 | ),
210 | ),
211 | );
212 | }
213 |
214 | /// build connection information display
215 | Widget _buildConnectionInfo() {
216 | return Container(
217 | padding: const EdgeInsets.all(16),
218 | decoration: BoxDecoration(
219 | color: Colors.white.withOpacity(0.1),
220 | borderRadius: BorderRadius.circular(12),
221 | border: Border.all(
222 | color: Colors.white.withOpacity(0.2),
223 | width: 1,
224 | ),
225 | ),
226 | child: Column(
227 | crossAxisAlignment: CrossAxisAlignment.start,
228 | children: [
229 | Row(
230 | children: [
231 | Icon(
232 | Icons.info_outline,
233 | size: 16,
234 | color: Colors.white.withOpacity(0.7),
235 | ),
236 | const SizedBox(width: 8),
237 | Text(
238 | 'Connection Info',
239 | style: TextStyle(
240 | fontSize: 14,
241 | fontWeight: FontWeight.w600,
242 | color: Colors.white.withOpacity(0.9),
243 | ),
244 | ),
245 | ],
246 | ),
247 | const SizedBox(height: 8),
248 | _buildInfoRow('Platform', Platform.isAndroid ? 'Android' : 'iOS'),
249 | _buildInfoRow('Test URL', _overwriteUrl ?? 'Not set'),
250 | _buildInfoRow('Control URL', _controlUrl),
251 | ],
252 | ),
253 | );
254 | }
255 |
256 | /// build an information row
257 | Widget _buildInfoRow(String label, String value) {
258 | return Padding(
259 | padding: const EdgeInsets.symmetric(vertical: 2),
260 | child: Row(
261 | crossAxisAlignment: CrossAxisAlignment.start,
262 | children: [
263 | SizedBox(
264 | width: 80,
265 | child: Text(
266 | '$label:',
267 | style: TextStyle(
268 | fontSize: 12,
269 | color: Colors.white.withOpacity(0.6),
270 | ),
271 | ),
272 | ),
273 | Expanded(
274 | child: Text(
275 | value,
276 | style: TextStyle(
277 | fontSize: 12,
278 | color: Colors.white.withOpacity(0.8),
279 | fontFamily: 'monospace',
280 | ),
281 | ),
282 | ),
283 | ],
284 | ),
285 | );
286 | }
287 | }
288 |
--------------------------------------------------------------------------------
/lib/adjust.dart:
--------------------------------------------------------------------------------
1 | //
2 | // adjust_sdk.dart
3 | // Adjust SDK
4 | //
5 | // Created by Srdjan Tubin (@2beens) on 25th April 2018.
6 | // Copyright (c) 2018-Present Adjust GmbH. All rights reserved.
7 | //
8 |
9 | import 'dart:async';
10 |
11 | import 'package:adjust_sdk/adjust_ad_revenue.dart';
12 | import 'package:adjust_sdk/adjust_app_store_subscription.dart';
13 | import 'package:adjust_sdk/adjust_app_store_purchase.dart';
14 | import 'package:adjust_sdk/adjust_attribution.dart';
15 | import 'package:adjust_sdk/adjust_config.dart';
16 | import 'package:adjust_sdk/adjust_event.dart';
17 | import 'package:adjust_sdk/adjust_play_store_purchase.dart';
18 | import 'package:adjust_sdk/adjust_play_store_subscription.dart';
19 | import 'package:adjust_sdk/adjust_purchase_verification_result.dart';
20 | import 'package:adjust_sdk/adjust_third_party_sharing.dart';
21 | import 'package:adjust_sdk/adjust_deeplink.dart';
22 |
23 | import 'package:flutter/services.dart';
24 | import 'package:meta/meta.dart';
25 |
26 | class Adjust {
27 | static const String _sdkPrefix = 'flutter5.5.0';
28 | static const MethodChannel _channel =
29 | const MethodChannel('com.adjust.sdk/api');
30 |
31 | // common
32 |
33 | static void initSdk(AdjustConfig config) {
34 | config.sdkPrefix = _sdkPrefix;
35 | _channel.invokeMethod('initSdk', config.toMap);
36 | }
37 |
38 | static void trackEvent(AdjustEvent event) {
39 | _channel.invokeMethod('trackEvent', event.toMap);
40 | }
41 |
42 | static void trackAdRevenue(AdjustAdRevenue adRevenue) {
43 | _channel.invokeMethod('trackAdRevenue', adRevenue.toMap);
44 | }
45 |
46 | static void trackThirdPartySharing(
47 | AdjustThirdPartySharing thirdPartySharing) {
48 | _channel.invokeMethod('trackThirdPartySharing', thirdPartySharing.toMap);
49 | }
50 |
51 | static void trackMeasurementConsent(bool measurementConsent) {
52 | _channel.invokeMethod(
53 | 'trackMeasurementConsent', {'measurementConsent': measurementConsent});
54 | }
55 |
56 | static void processDeeplink(AdjustDeeplink deeplink) {
57 | _channel.invokeMethod('processDeeplink', deeplink.toMap);
58 | }
59 |
60 | static Future processAndResolveDeeplink(AdjustDeeplink deeplink) async {
61 | final resolvedLink =
62 | await _channel.invokeMethod('processAndResolveDeeplink', deeplink.toMap);
63 | return resolvedLink;
64 | }
65 |
66 | static void setPushToken(String token) {
67 | _channel.invokeMethod('setPushToken', {'pushToken': token});
68 | }
69 |
70 | static void gdprForgetMe() {
71 | _channel.invokeMethod('gdprForgetMe');
72 | }
73 |
74 | static void enable() {
75 | _channel.invokeMethod('enable');
76 | }
77 |
78 | static void disable() {
79 | _channel.invokeMethod('disable');
80 | }
81 |
82 | static void switchToOfflineMode() {
83 | _channel.invokeMethod('switchToOfflineMode');
84 | }
85 |
86 | static void switchBackToOnlineMode() {
87 | _channel.invokeMethod('switchBackToOnlineMode');
88 | }
89 |
90 | static void addGlobalCallbackParameter(String key, String value) {
91 | _channel.invokeMethod(
92 | 'addGlobalCallbackParameter', {'key': key, 'value': value});
93 | }
94 |
95 | static void addGlobalPartnerParameter(String key, String value) {
96 | _channel.invokeMethod(
97 | 'addGlobalPartnerParameter', {'key': key, 'value': value});
98 | }
99 |
100 | static void removeGlobalCallbackParameter(String key) {
101 | _channel.invokeMethod('removeGlobalCallbackParameter', {'key': key});
102 | }
103 |
104 | static void removeGlobalPartnerParameter(String key) {
105 | _channel.invokeMethod('removeGlobalPartnerParameter', {'key': key});
106 | }
107 |
108 | static void removeGlobalCallbackParameters() {
109 | _channel.invokeMethod('removeGlobalCallbackParameters');
110 | }
111 |
112 | static void removeGlobalPartnerParameters() {
113 | _channel.invokeMethod('removeGlobalPartnerParameters');
114 | }
115 |
116 | static void endFirstSessionDelay() {
117 | _channel.invokeMethod('endFirstSessionDelay');
118 | }
119 |
120 | static void enableCoppaComplianceInDelay() {
121 | _channel.invokeMethod('enableCoppaComplianceInDelay');
122 | }
123 |
124 | static void disableCoppaComplianceInDelay() {
125 | _channel.invokeMethod('disableCoppaComplianceInDelay');
126 | }
127 |
128 | static void setExternalDeviceIdInDelay(String externalDeviceId) {
129 | _channel.invokeMethod('setExternalDeviceIdInDelay',{'externalDeviceId': externalDeviceId});
130 | }
131 |
132 | static Future isEnabled() async {
133 | final bool isEnabled = await _channel.invokeMethod('isEnabled');
134 | return isEnabled;
135 | }
136 |
137 | static Future getAdid() async {
138 | final String? adid = await _channel.invokeMethod('getAdid');
139 | return adid;
140 | }
141 |
142 | static Future getAdidWithTimeout(int timeoutInMilliseconds) async {
143 | final String? adid = await _channel.invokeMethod('getAdidWithTimeout', {'timeoutInMilliseconds': timeoutInMilliseconds});
144 | return adid;
145 | }
146 |
147 | static Future getAttribution() async {
148 | final dynamic attributionMap =
149 | await _channel.invokeMethod('getAttribution');
150 | return AdjustAttribution.fromMap(attributionMap);
151 | }
152 |
153 | static Future getAttributionWithTimeout(int timeoutInMilliseconds) async {
154 | final dynamic attributionMap =
155 | await _channel.invokeMethod('getAttributionWithTimeout', {'timeoutInMilliseconds': timeoutInMilliseconds});
156 | if (attributionMap == null) {
157 | return null;
158 | }
159 | return AdjustAttribution.fromMap(attributionMap);
160 | }
161 |
162 | static Future getLastDeeplink() async {
163 | final String? deeplink = await _channel.invokeMethod('getLastDeeplink');
164 | return deeplink;
165 | }
166 |
167 | static Future getSdkVersion() async {
168 | final String sdkVersion = await _channel.invokeMethod('getSdkVersion');
169 | return _sdkPrefix + '@' + sdkVersion;
170 | }
171 |
172 | // ios only
173 |
174 | static void trackAppStoreSubscription(
175 | AdjustAppStoreSubscription subscription) {
176 | _channel.invokeMethod('trackAppStoreSubscription', subscription.toMap);
177 | }
178 |
179 | static Future verifyAppStorePurchase(
180 | AdjustAppStorePurchase purchase) async {
181 | final dynamic appStorePurchaseMap =
182 | await _channel.invokeMethod('verifyAppStorePurchase', purchase.toMap);
183 | return AdjustPurchaseVerificationResult.fromMap(appStorePurchaseMap);
184 | }
185 |
186 | static Future verifyAndTrackAppStorePurchase(
187 | AdjustEvent event) async {
188 | final dynamic appStorePurchaseMap =
189 | await _channel.invokeMethod('verifyAndTrackAppStorePurchase', event.toMap);
190 | return AdjustPurchaseVerificationResult.fromMap(appStorePurchaseMap);
191 | }
192 |
193 | static Future requestAppTrackingAuthorization() async {
194 | final num status = await _channel
195 | .invokeMethod('requestAppTrackingAuthorization');
196 | return status;
197 | }
198 |
199 | static Future updateSkanConversionValue(int conversionValue, String coarseValue, bool lockWindow) async {
200 | final String? error = await _channel.invokeMethod('updateSkanConversionValue', {
201 | 'conversionValue': conversionValue,
202 | 'coarseValue': coarseValue,
203 | 'lockWindow': lockWindow
204 | });
205 | return error;
206 | }
207 |
208 | static Future getIdfa() async {
209 | final String? idfa = await _channel.invokeMethod('getIdfa');
210 | return idfa;
211 | }
212 |
213 | static Future getIdfv() async {
214 | final String? idfv = await _channel.invokeMethod('getIdfv');
215 | return idfv;
216 | }
217 |
218 | static Future getAppTrackingAuthorizationStatus() async {
219 | final int authorizationStatus =
220 | await _channel.invokeMethod('getAppTrackingAuthorizationStatus');
221 | return authorizationStatus;
222 | }
223 |
224 | // android only
225 |
226 | static void trackPlayStoreSubscription(
227 | AdjustPlayStoreSubscription subscription) {
228 | _channel.invokeMethod('trackPlayStoreSubscription', subscription.toMap);
229 | }
230 |
231 | static Future verifyPlayStorePurchase(
232 | AdjustPlayStorePurchase purchase) async {
233 | final dynamic playStorePurchaseMap =
234 | await _channel.invokeMethod('verifyPlayStorePurchase', purchase.toMap);
235 | return AdjustPurchaseVerificationResult.fromMap(playStorePurchaseMap);
236 | }
237 |
238 | static Future verifyAndTrackPlayStorePurchase(
239 | AdjustEvent event) async {
240 | final dynamic playStorePurchaseMap =
241 | await _channel.invokeMethod('verifyAndTrackPlayStorePurchase', event.toMap);
242 | return AdjustPurchaseVerificationResult.fromMap(playStorePurchaseMap);
243 | }
244 |
245 | static void enablePlayStoreKidsComplianceInDelay() {
246 | _channel.invokeMethod('enablePlayStoreKidsComplianceInDelay');
247 | }
248 |
249 | static void disablePlayStoreKidsComplianceInDelay() {
250 | _channel.invokeMethod('disablePlayStoreKidsComplianceInDelay');
251 | }
252 |
253 | static Future getAmazonAdId() async {
254 | final String? amazonAdId = await _channel.invokeMethod('getAmazonAdId');
255 | return amazonAdId;
256 | }
257 |
258 | static Future getGoogleAdId() async {
259 | final String? googleAdId = await _channel.invokeMethod('getGoogleAdId');
260 | return googleAdId;
261 | }
262 |
263 | // for testing purposes only, do not use in production!
264 |
265 | @visibleForTesting
266 | static void onResume() {
267 | _channel.invokeMethod('onResume');
268 | }
269 |
270 | @visibleForTesting
271 | static void onPause() {
272 | _channel.invokeMethod('onPause');
273 | }
274 |
275 | @visibleForTesting
276 | static void setTestOptions(final dynamic testOptions) {
277 | _channel.invokeMethod('setTestOptions', testOptions);
278 | }
279 | }
280 |
--------------------------------------------------------------------------------