diff --git a/ChangeLog.txt b/ChangeLog.txt
index b091e8226..835055df8 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,5 +1,25 @@
Google Mobile Ads Unity Plugin Change Log
+**************
+Version 3.11.0
+**************
+
+Plugin:
+- Updated Android ad events to be invoked on the main thread.
+- Added `MobileAds.SetiOSAppPauseOnBackground()` method to pause iOS apps when
+displaying full screen ads.
+- Fixed issue were banners repositioned incorrectly following an orienation
+change.
+
+Mediation packages:
+- Added maio mediation support package.
+- Added nend mediation support package.
+
+Built and tested with:
+- Google Play services 11.8.0
+- Google Mobile Ads iOS SDK 7.27.0
+- Unity Jar Resolver 1.2.61.0
+
**************
Version 3.10.0
**************
diff --git a/mediation/AppLovin/CHANGELOG.md b/mediation/AppLovin/CHANGELOG.md
index f8cfbb9e6..602790498 100644
--- a/mediation/AppLovin/CHANGELOG.md
+++ b/mediation/AppLovin/CHANGELOG.md
@@ -1,7 +1,11 @@
# AppLovin Adapter plugin for Google Mobile Ads SDK for Unity 3D Changelog
+## 1.1.0
+- Supports AppLovin Android SDK version 7.7.0.
+- Supports AppLovin iOS SDK version 4.7.0.
+
## 1.0.0
- First release!
-- Supports Android adapter version 7.4.1.1.
-- Supports iOS adapter version 4.4.1.1.
+- Supports AppLovin Android SDK version 7.4.1.
+- Supports AppLovin iOS SDK version 4.4.1.
diff --git a/mediation/AppLovin/build.gradle b/mediation/AppLovin/build.gradle
index b60e3b83d..0e28180be 100644
--- a/mediation/AppLovin/build.gradle
+++ b/mediation/AppLovin/build.gradle
@@ -23,7 +23,7 @@ project.ext {
'UNITY_EXE environment variable and point it to your Unity installation.')
}
- versionString = '1.0.0'
+ versionString = '1.1.0'
pluginName = 'GoogleMobileAdsAppLovinMediation'
pluginFileName = "${pluginName}.unitypackage"
zipName = "${pluginName}-${versionString}"
diff --git a/mediation/AppLovin/source/plugin/Assets/GoogleMobileAds/Editor/AppLovinMediationDependencies.xml b/mediation/AppLovin/source/plugin/Assets/GoogleMobileAds/Editor/AppLovinMediationDependencies.xml
index 0d3407ea8..7e46cca41 100644
--- a/mediation/AppLovin/source/plugin/Assets/GoogleMobileAds/Editor/AppLovinMediationDependencies.xml
+++ b/mediation/AppLovin/source/plugin/Assets/GoogleMobileAds/Editor/AppLovinMediationDependencies.xml
@@ -1,17 +1,16 @@
-
+
-
+
-
+
-
diff --git a/mediation/InMobi/build.gradle b/mediation/InMobi/build.gradle
index 7b273a3ec..642f6b72a 100644
--- a/mediation/InMobi/build.gradle
+++ b/mediation/InMobi/build.gradle
@@ -46,6 +46,7 @@ task exportPackage(type: Exec) {
"-logFile", "temp/unity.log",
"-exportPackage",
"Assets/GoogleMobileAds/Editor",
+ "Assets/Plugins",
"${exportPath}",
"-quit"
diff --git a/mediation/InMobi/source/plugin/Assets/GoogleMobileAds/Plugins/Android/GoogleMobileAdsInMobiMediation/AndroidManifest.xml b/mediation/InMobi/source/plugin/Assets/Plugins/Android/GoogleMobileAdsInMobiMediation/AndroidManifest.xml
similarity index 100%
rename from mediation/InMobi/source/plugin/Assets/GoogleMobileAds/Plugins/Android/GoogleMobileAdsInMobiMediation/AndroidManifest.xml
rename to mediation/InMobi/source/plugin/Assets/Plugins/Android/GoogleMobileAdsInMobiMediation/AndroidManifest.xml
diff --git a/mediation/InMobi/source/plugin/Assets/GoogleMobileAds/Plugins/Android/GoogleMobileAdsInMobiMediation/project.properties b/mediation/InMobi/source/plugin/Assets/Plugins/Android/GoogleMobileAdsInMobiMediation/project.properties
similarity index 100%
rename from mediation/InMobi/source/plugin/Assets/GoogleMobileAds/Plugins/Android/GoogleMobileAdsInMobiMediation/project.properties
rename to mediation/InMobi/source/plugin/Assets/Plugins/Android/GoogleMobileAdsInMobiMediation/project.properties
diff --git a/mediation/Maio/CHANGELOG.md b/mediation/Maio/CHANGELOG.md
new file mode 100644
index 000000000..b6ac736d8
--- /dev/null
+++ b/mediation/Maio/CHANGELOG.md
@@ -0,0 +1,7 @@
+# maio Adapter plugin for Google Mobile Ads SDK for Unity 3D Changelog
+
+## 1.0.0
+
+- First release!
+- Supports Android adapter version 1.0.6.0.
+- Supports iOS adapter version 1.2.18.0.
diff --git a/mediation/Maio/README.md b/mediation/Maio/README.md
new file mode 100644
index 000000000..851f2d2f2
--- /dev/null
+++ b/mediation/Maio/README.md
@@ -0,0 +1,5 @@
+# maio Adapter plugin for Google Mobile Ads SDK for Unity 3D
+
+This is a plugin to be used in conjunction with the Google Mobile Ads SDK in
+Google Play services. For requirements, instructions, and other info, see the
+[maio Adapter Integration Guide](https://developers.google.com/admob/unity/mediation/maio).
diff --git a/mediation/Maio/build.gradle b/mediation/Maio/build.gradle
new file mode 100644
index 000000000..b94c6ccc2
--- /dev/null
+++ b/mediation/Maio/build.gradle
@@ -0,0 +1,145 @@
+/*
+* Gradle file to build a Unity package to add maio mediation support to the Google Mobile Ads Unity plugin.
+* Usage: ./gradlew exportPackage
+*/
+plugins {
+ id "com.jfrog.bintray" version "1.7.3"
+}
+
+defaultTasks 'exportPackage'
+
+// Project level variables.
+project.ext {
+ unity_exe = System.getProperty("UNITY_EXE")
+ if (unity_exe == null || unity_exe.isEmpty()) {
+ unity_exe = System.getenv("UNITY_EXE")
+ }
+ if (unity_exe == null || unity_exe.isEmpty()) {
+ unity_exe = '/Applications/Unity/Unity.app/Contents/MacOS/Unity'
+ }
+
+ if (!file(unity_exe).exists()) {
+ throw new GradleException('Unable to locate installation of Unity. Please create a ' +
+ 'UNITY_EXE environment variable and point it to your Unity installation.')
+ }
+
+ versionString = '1.0.0'
+ pluginName = 'GoogleMobileAdsMaioMediation'
+ pluginFileName = "${pluginName}.unitypackage"
+ zipName = "${pluginName}-${versionString}"
+ zipFileName = "${zipName}.zip"
+ pluginSource = file('source/plugin').absolutePath
+ pluginBuildDir = file('temp/plugin-build-dir').absolutePath
+ buildPath = file('temp').absolutePath
+ exportPath = file(pluginFileName).absolutePath
+}
+
+// Build unity package using through command line interface.
+// Create new unity project with files in temporary build directory and export files to a unity package.
+// Command line usage and arguments documented at http://docs.unity3d.com/Manual/CommandLineArguments.html.
+task exportPackage(type: Exec) {
+ description = "Creates and exports the Plugin unity package"
+ executable "${unity_exe}"
+ args "-g.building",
+ "-batchmode",
+ "-projectPath", "${pluginBuildDir}",
+ "-logFile", "temp/unity.log",
+ "-exportPackage",
+ "Assets/GoogleMobileAds/Editor",
+ "Assets/Plugins",
+ "${exportPath}",
+ "-quit"
+
+ ignoreExitValue true
+
+ doLast {
+ if (execResult.getExitValue() != 0) {
+ copy {
+ from "temp/"
+ into "./"
+ include "unity.log"
+ }
+ }
+ }
+}
+
+task createTempBuildFolder(type: Copy) {
+ from { "${pluginSource}" }
+ into { "${pluginBuildDir}" }
+}
+
+task clearTempBuildFolder(type: Delete) {
+ delete { "${buildPath}" }
+}
+
+exportPackage.dependsOn(createTempBuildFolder)
+exportPackage.finalizedBy(clearTempBuildFolder)
+
+/**
+ * Delete task to delete any previously generated .zip files by makeZip task.
+ * makeZip depends on this task.
+ */
+task clearZip(type: Delete) {
+ // Targets to be deleted.
+ delete(zipFileName)
+}
+
+/**
+ * Zip task to make a zip archive. This task depends on exportPackage and clearZip tasks.
+ */
+task makeZip(type: Zip) {
+ // Targets to be added to the zip archive.
+ from('./' + pluginFileName, './README.md', './CHANGELOG.md')
+ // Root directory name for the zip archive.
+ into(zipName)
+ // Name of the zip archive.
+ archiveName zipFileName
+ // Destination directory in which the archive needs to be saved.
+ destinationDir file('.')
+}
+
+makeZip.dependsOn([clearZip, exportPackage])
+makeZip.mustRunAfter([clearZip, exportPackage])
+
+/**
+ * Bintray closure needed to run the bintrayUpload task.
+ *
+ * Usage:
+ * ./gradlew bintrayUpload -PbintrayUser=YOUR_BINTRAY_USER_ID -PbintrayApiKey=YOUR_BINTRAY_API_KEY
+ *
+ * The Bintray User ID and API key can be added to your system environment variables as BINTRAY_USER
+ * and BINTRAY_API_KEY respectively, and the command can be reduced to:
+ * ./gradlew bintrayUpload
+ */
+bintray {
+ user = project.hasProperty('bintrayUser') ? project.property('bintrayUser')
+ : System.getenv('BINTRAY_USER')
+ key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey')
+ : System.getenv('BINTRAY_API_KEY')
+
+ filesSpec { // 'filesSpec' is a standard Gradle CopySpec
+ from zipFileName
+ into "${pluginName}/${versionString}"
+ }
+ dryRun = false // Deploy after running.
+ publish = false // Don't auto publish after deploying.
+ override = false // Don't override existing version artifacts that are already published.
+
+ pkg {
+ repo = 'mobile-ads-adapters-unity'
+ name = pluginName
+ userOrg = 'google'
+ desc = 'maio plugin for Google Mobile Ads Mediation.'
+ websiteUrl = 'https://developers.google.com/admob/unity/mediation/maio'
+ issueTrackerUrl = 'https://github.com/googleads/googleads-mobile-unity/issues'
+ vcsUrl = 'https://github.com/googleads/googleads-mobile-unity'
+ licenses = ['Apache-2.0']
+
+ version {
+ name = versionString
+ }
+ }
+}
+
+bintrayUpload.dependsOn(makeZip)
+bintrayUpload.mustRunAfter(makeZip)
diff --git a/mediation/Maio/source/plugin/Assets/GoogleMobileAds/Editor/MaioMediationDependencies.xml b/mediation/Maio/source/plugin/Assets/GoogleMobileAds/Editor/MaioMediationDependencies.xml
new file mode 100644
index 000000000..28690f55d
--- /dev/null
+++ b/mediation/Maio/source/plugin/Assets/GoogleMobileAds/Editor/MaioMediationDependencies.xml
@@ -0,0 +1,22 @@
+
+
+
+
+ https://jcenter.bintray.com/
+
+
+
+
+ https://imobile-maio.github.io/maven
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mediation/Maio/source/plugin/Assets/Plugins/Android/GoogleMobileAdsMaioMediation/AndroidManifest.xml b/mediation/Maio/source/plugin/Assets/Plugins/Android/GoogleMobileAdsMaioMediation/AndroidManifest.xml
new file mode 100644
index 000000000..49a05303c
--- /dev/null
+++ b/mediation/Maio/source/plugin/Assets/Plugins/Android/GoogleMobileAdsMaioMediation/AndroidManifest.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mediation/Maio/source/plugin/Assets/Plugins/Android/GoogleMobileAdsMaioMediation/project.properties b/mediation/Maio/source/plugin/Assets/Plugins/Android/GoogleMobileAdsMaioMediation/project.properties
new file mode 100644
index 000000000..3a387fb86
--- /dev/null
+++ b/mediation/Maio/source/plugin/Assets/Plugins/Android/GoogleMobileAdsMaioMediation/project.properties
@@ -0,0 +1,2 @@
+target=android-26
+android.library=true
diff --git a/mediation/Nend/CHANGELOG.md b/mediation/Nend/CHANGELOG.md
new file mode 100644
index 000000000..f4416428a
--- /dev/null
+++ b/mediation/Nend/CHANGELOG.md
@@ -0,0 +1,7 @@
+# nend Adapter plugin for Google Mobile Ads SDK for Unity 3D Changelog
+
+## 1.0.0
+
+- First release!
+- Supports nend Android SDK version 4.0.2.
+- Supports nend iOS SDK version 4.0.2.
diff --git a/mediation/Nend/README.md b/mediation/Nend/README.md
new file mode 100644
index 000000000..e198ee222
--- /dev/null
+++ b/mediation/Nend/README.md
@@ -0,0 +1,6 @@
+# nend Adapter plugin for Google Mobile Ads SDK for Unity 3D
+
+This is a plugin to be used in conjunction with the Google Mobile Ads SDK in
+Google Play services. For requirements, instructions, and other info, see the
+[nend Adapter Integration Guide](https://developers.google.com/admob/unity/mediation/nend).
+
diff --git a/mediation/Nend/build.gradle b/mediation/Nend/build.gradle
new file mode 100644
index 000000000..0ce3b3a22
--- /dev/null
+++ b/mediation/Nend/build.gradle
@@ -0,0 +1,144 @@
+/*
+* Gradle file to build a Unity package to add nend mediation support to the Google Mobile Ads Unity plugin.
+* Usage: ./gradlew exportPackage
+*/
+plugins {
+ id "com.jfrog.bintray" version "1.7.3"
+}
+
+defaultTasks 'exportPackage'
+
+// Project level variables.
+project.ext {
+ unity_exe = System.getProperty("UNITY_EXE")
+ if (unity_exe == null || unity_exe.isEmpty()) {
+ unity_exe = System.getenv("UNITY_EXE")
+ }
+ if (unity_exe == null || unity_exe.isEmpty()) {
+ unity_exe = '/Applications/Unity/Unity.app/Contents/MacOS/Unity'
+ }
+
+ if (!file(unity_exe).exists()) {
+ throw new GradleException('Unable to locate installation of Unity. Please create a ' +
+ 'UNITY_EXE environment variable and point it to your Unity installation.')
+ }
+
+ versionString = '1.0.0'
+ pluginName = 'GoogleMobileAdsNendMediation'
+ pluginFileName = "${pluginName}.unitypackage"
+ zipName = "${pluginName}-${versionString}"
+ zipFileName = "${zipName}.zip"
+ pluginSource = file('source/plugin').absolutePath
+ pluginBuildDir = file('temp/plugin-build-dir').absolutePath
+ buildPath = file('temp').absolutePath
+ exportPath = file(pluginFileName).absolutePath
+}
+
+// Build unity package using through command line interface.
+// Create new unity project with files in temporary build directory and export files to a unity package.
+// Command line usage and arguments documented at http://docs.unity3d.com/Manual/CommandLineArguments.html.
+task exportPackage(type: Exec) {
+ description = "Creates and exports the Plugin unity package"
+ executable "${unity_exe}"
+ args "-g.building",
+ "-batchmode",
+ "-projectPath", "${pluginBuildDir}",
+ "-logFile", "temp/unity.log",
+ "-exportPackage",
+ "Assets/GoogleMobileAds/Editor",
+ "${exportPath}",
+ "-quit"
+
+ ignoreExitValue true
+
+ doLast {
+ if (execResult.getExitValue() != 0) {
+ copy {
+ from "temp/"
+ into "./"
+ include "unity.log"
+ }
+ }
+ }
+}
+
+task createTempBuildFolder(type: Copy) {
+ from { "${pluginSource}" }
+ into { "${pluginBuildDir}" }
+}
+
+task clearTempBuildFolder(type: Delete) {
+ delete { "${buildPath}" }
+}
+
+exportPackage.dependsOn(createTempBuildFolder)
+exportPackage.finalizedBy(clearTempBuildFolder)
+
+/**
+ * Delete task to delete any previously generated .zip files by makeZip task.
+ * makeZip depends on this task.
+ */
+task clearZip(type: Delete) {
+ // Targets to be deleted.
+ delete(zipFileName)
+}
+
+/**
+ * Zip task to make a zip archive. This task depends on exportPackage and clearZip tasks.
+ */
+task makeZip(type: Zip) {
+ // Targets to be added to the zip archive.
+ from('./' + pluginFileName, './README.md', './CHANGELOG.md')
+ // Root directory name for the zip archive.
+ into(zipName)
+ // Name of the zip archive.
+ archiveName zipFileName
+ // Destination directory in which the archive needs to be saved.
+ destinationDir file('.')
+}
+
+makeZip.dependsOn([clearZip, exportPackage])
+makeZip.mustRunAfter([clearZip, exportPackage])
+
+/**
+ * Bintray closure needed to run the bintrayUpload task.
+ *
+ * Usage:
+ * ./gradlew bintrayUpload -PbintrayUser=YOUR_BINTRAY_USER_ID -PbintrayApiKey=YOUR_BINTRAY_API_KEY
+ *
+ * The Bintray User ID and API key can be added to your system environment variables as BINTRAY_USER
+ * and BINTRAY_API_KEY respectively, and the command can be reduced to:
+ * ./gradlew bintrayUpload
+ */
+bintray {
+ user = project.hasProperty('bintrayUser') ? project.property('bintrayUser')
+ : System.getenv('BINTRAY_USER')
+ key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey')
+ : System.getenv('BINTRAY_API_KEY')
+
+ filesSpec { // 'filesSpec' is a standard Gradle CopySpec
+ from zipFileName
+ into "${pluginName}/${versionString}"
+ }
+ dryRun = false // Deploy after running.
+ publish = false // Don't auto publish after deploying.
+ override = false // Don't override existing version artifacts that are already published.
+
+ pkg {
+ repo = 'mobile-ads-adapters-unity'
+ name = pluginName
+ userOrg = 'google'
+ desc = 'nend plugin for Google Mobile Ads Mediation.'
+ websiteUrl = 'https://developers.google.com/admob/unity/mediation/nend'
+ issueTrackerUrl = 'https://github.com/googleads/googleads-mobile-unity/issues'
+ vcsUrl = 'https://github.com/googleads/googleads-mobile-unity'
+ licenses = ['Apache-2.0']
+
+ version {
+ name = versionString
+ }
+ }
+}
+
+bintrayUpload.dependsOn(makeZip)
+bintrayUpload.mustRunAfter(makeZip)
diff --git a/mediation/Nend/source/plugin/Assets/GoogleMobileAds/Editor/NendMediationDependencies.xml b/mediation/Nend/source/plugin/Assets/GoogleMobileAds/Editor/NendMediationDependencies.xml
new file mode 100644
index 000000000..9cdeab674
--- /dev/null
+++ b/mediation/Nend/source/plugin/Assets/GoogleMobileAds/Editor/NendMediationDependencies.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ https://jcenter.bintray.com/
+
+
+
+
+ http://fan-adn.github.io/nendSDK-Android-lib/library
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mediation/Tapjoy/CHANGELOG.md b/mediation/Tapjoy/CHANGELOG.md
new file mode 100644
index 000000000..320285737
--- /dev/null
+++ b/mediation/Tapjoy/CHANGELOG.md
@@ -0,0 +1,7 @@
+# Tapjoy Adapter plugin for Google Mobile Ads SDK for Unity 3D Changelog
+
+## 1.0.0
+
+- First release!
+- Supports Tapjoy Android SDK version 11.11.1.
+- Supports Tapjoy iOS SDK version 11.11.1.
diff --git a/mediation/Tapjoy/README.md b/mediation/Tapjoy/README.md
new file mode 100644
index 000000000..b873cab3b
--- /dev/null
+++ b/mediation/Tapjoy/README.md
@@ -0,0 +1,6 @@
+# Tapjoy Adapter plugin for Google Mobile Ads SDK for Unity 3D
+
+This is a plugin to be used in conjunction with the Google Mobile Ads SDK in
+Google Play services. For requirements, instructions, and other info, see the
+[Tapjoy Adapter Integration Guide](https://developers.google.com/admob/unity/mediation/tapjoy).
+
diff --git a/mediation/Tapjoy/build.gradle b/mediation/Tapjoy/build.gradle
index 43b480b58..7d02415c4 100644
--- a/mediation/Tapjoy/build.gradle
+++ b/mediation/Tapjoy/build.gradle
@@ -2,6 +2,9 @@
* Gradle file to build a Unity package to add Tapjoy mediation support to the Google Mobile Ads Unity plugin.
* Usage: ./gradlew exportPackage
*/
+plugins {
+ id "com.jfrog.bintray" version "1.7.3"
+}
defaultTasks 'exportPackage'
@@ -20,10 +23,15 @@ project.ext {
'UNITY_EXE environment variable and point it to your Unity installation.')
}
+ versionString = '1.0.0'
+ pluginName = 'GoogleMobileAdsTapjoyMediation'
+ pluginFileName = "${pluginName}.unitypackage"
+ zipName = "${pluginName}-${versionString}"
+ zipFileName = "${zipName}.zip"
pluginSource = file('source/plugin').absolutePath
pluginBuildDir = file('temp/plugin-build-dir').absolutePath
buildPath = file('temp').absolutePath
- exportPath = file('GoogleMobileAdsTapjoyMediation.unitypackage').absolutePath
+ exportPath = file(pluginFileName).absolutePath
}
// Build unity package using through command line interface.
@@ -66,3 +74,72 @@ task clearTempBuildFolder(type: Delete) {
exportPackage.dependsOn(createTempBuildFolder)
exportPackage.finalizedBy(clearTempBuildFolder)
+
+/**
+ * Delete task to delete any previously generated .zip files by makeZip task.
+ * makeZip depends on this task.
+ */
+task clearZip(type: Delete) {
+ // Targets to be deleted.
+ delete(zipFileName)
+}
+
+/**
+ * Zip task to make a zip archive. This task depends on exportPackage and clearZip tasks.
+ */
+task makeZip(type: Zip) {
+ // Targets to be added to the zip archive.
+ from("./${pluginFileName}", "./README.md", "./CHANGELOG.md")
+ // Root directory name for the zip archive.
+ into(zipName)
+ // Name of the zip archive.
+ archiveName zipFileName
+ // Destination directory in which the archive needs to be saved.
+ destinationDir file('.')
+}
+
+makeZip.dependsOn([clearZip, exportPackage])
+makeZip.mustRunAfter([clearZip, exportPackage])
+
+/**
+ * Bintray closure needed to run the bintrayUpload task.
+ *
+ * Usage:
+ * ./gradlew bintrayUpload -PbintrayUser=YOUR_BINTRAY_USER_ID -PbintrayApiKey=YOUR_BINTRAY_API_KEY
+ *
+ * The Bintray User ID and API key can be added to your system environment variables as BINTRAY_USER
+ * and BINTRAY_API_KEY respectively, and the command can be reduced to:
+ * ./gradlew bintrayUpload
+ */
+bintray {
+ user = project.hasProperty('bintrayUser') ? project.property('bintrayUser')
+ : System.getenv('BINTRAY_USER')
+ key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey')
+ : System.getenv('BINTRAY_API_KEY')
+
+ filesSpec { // 'filesSpec' is a standard Gradle CopySpec
+ from zipFileName
+ into "${pluginName}/${versionString}"
+ }
+ dryRun = false // Deploy after running.
+ publish = false // Don't auto publish after deploying.
+ override = false // Don't override existing version artifacts that are already published.
+
+ pkg {
+ repo = 'mobile-ads-adapters-unity'
+ name = pluginName
+ userOrg = 'google'
+ desc = 'Tapjoy plugin for Google Mobile Ads Mediation.'
+ websiteUrl = 'https://developers.google.com/admob/unity/mediation/tapjoy'
+ issueTrackerUrl = 'https://github.com/googleads/googleads-mobile-unity/issues'
+ vcsUrl = 'https://github.com/googleads/googleads-mobile-unity'
+ licenses = ['Apache-2.0']
+
+ version {
+ name = versionString
+ }
+ }
+}
+
+bintrayUpload.dependsOn(makeZip)
+bintrayUpload.mustRunAfter(makeZip)
diff --git a/samples/HelloWorld/Assets/Scripts/GoogleMobileAdsDemoScript.cs b/samples/HelloWorld/Assets/Scripts/GoogleMobileAdsDemoScript.cs
index 4aab941ad..115b8f48b 100644
--- a/samples/HelloWorld/Assets/Scripts/GoogleMobileAdsDemoScript.cs
+++ b/samples/HelloWorld/Assets/Scripts/GoogleMobileAdsDemoScript.cs
@@ -29,6 +29,8 @@ public void Start()
string appId = "unexpected_platform";
#endif
+ MobileAds.SetiOSAppPauseOnBackground(true);
+
// Initialize the Google Mobile Ads SDK.
MobileAds.Initialize(appId);
diff --git a/source/android-library/app/build.gradle b/source/android-library/app/build.gradle
index f79ba7c24..681be6ed2 100644
--- a/source/android-library/app/build.gradle
+++ b/source/android-library/app/build.gradle
@@ -24,7 +24,7 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
api 'com.android.support:appcompat-v7:26.1.0'
- api 'com.google.android.gms:play-services-ads:11.6.2'
+ api 'com.google.android.gms:play-services-ads:11.8.0'
}
task clearJar(type: Delete) {
diff --git a/source/android-library/app/src/main/java/com/google/unity/ads/Banner.java b/source/android-library/app/src/main/java/com/google/unity/ads/Banner.java
index b95641041..9dead1064 100644
--- a/source/android-library/app/src/main/java/com/google/unity/ads/Banner.java
+++ b/source/android-library/app/src/main/java/com/google/unity/ads/Banner.java
@@ -18,14 +18,13 @@
import android.app.Activity;
import android.graphics.Color;
import android.graphics.Point;
-import android.os.Build;
import android.util.Log;
-import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.WindowManager;
import android.widget.PopupWindow;
+
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
@@ -81,6 +80,12 @@ public class Banner {
*/
private UnityAdListener mUnityListener;
+ /**
+ * A {@code View.OnLayoutChangeListener} used to detect orientation changes and reposition
+ * banner ads as required.
+ */
+ private View.OnLayoutChangeListener mLayoutChangeListener;
+
/**
* Creates an instance of {@code Banner}.
*
@@ -182,6 +187,18 @@ public void onAdLeftApplication() {
}
}
});
+
+ mLayoutChangeListener = new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ if (mPopupWindow.isShowing() && !mHidden) {
+ updatePosition();
+ }
+ }
+ };
+ mUnityPlayerActivity.getWindow().getDecorView().getRootView()
+ .addOnLayoutChangeListener(mLayoutChangeListener);
}
private void createPopupWindow() {
@@ -280,10 +297,14 @@ public void run() {
}
}
});
+
+ mUnityPlayerActivity.getWindow().getDecorView().getRootView()
+ .removeOnLayoutChangeListener(mLayoutChangeListener);
}
/**
* Get {@link AdView} height.
+ *
* @return the height of the {@link AdView}.
*/
public float getHeightInPixels() {
@@ -292,6 +313,7 @@ public float getHeightInPixels() {
/**
* Get {@link AdView} width.
+ *
* @return the width of the {@link AdView}.
*/
public float getWidthInPixels() {
@@ -316,8 +338,8 @@ public void run() {
/**
* Updates the {@link AdView} position.
*
- * @param positionX Position of banner ad on the x axis.
- * @param positionY Position of banner ad on the y axis.
+ * @param positionX Position of banner ad on the x axis.
+ * @param positionY Position of banner ad on the y axis.
*/
public void setPosition(final int positionX, final int positionY) {
mUnityPlayerActivity.runOnUiThread(new Runnable() {
@@ -335,7 +357,6 @@ public void run() {
* Update the {@link AdView} position based on current parameters.
*/
private void updatePosition() {
-
if (mPopupWindow != null && mPopupWindow.isShowing()) {
View anchorView = mUnityPlayerActivity.getWindow().getDecorView().getRootView();
Point location = getPositionInPixels(anchorView);
@@ -351,6 +372,7 @@ private void updatePosition() {
* Gets the location for the PopUp window based on the current position code / offset and ad
* view size. The location is in bottom left coordinate system as per the showAsDropDown and
* update methods requirements.
+ *
* @param anchorView the anchorview to position against.
* @return the position point in pixels in the bottom left coordinate system.
*/
diff --git a/source/plugin/Assets/GoogleMobileAds/Api/AdLoader.cs b/source/plugin/Assets/GoogleMobileAds/Api/AdLoader.cs
index 497a3e082..a1f319e0a 100644
--- a/source/plugin/Assets/GoogleMobileAds/Api/AdLoader.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Api/AdLoader.cs
@@ -45,12 +45,14 @@ private AdLoader(Builder builder)
BindingFlags.Static | BindingFlags.Public);
this.adLoaderClient = (IAdLoaderClient)method.Invoke(null, new object[] { this });
+ Utils.CheckInitialization();
+
this.adLoaderClient.OnCustomNativeTemplateAdLoaded +=
delegate (object sender, CustomNativeEventArgs args)
{
if (this.OnCustomNativeTemplateAdLoaded != null)
{
- this.OnCustomNativeTemplateAdLoaded(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnCustomNativeTemplateAdLoaded(this, args));
}
};
this.adLoaderClient.OnAdFailedToLoad += delegate (
@@ -58,7 +60,7 @@ private AdLoader(Builder builder)
{
if (this.OnAdFailedToLoad != null)
{
- this.OnAdFailedToLoad(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdFailedToLoad(this, args));
}
};
}
diff --git a/source/plugin/Assets/GoogleMobileAds/Api/AdRequest.cs b/source/plugin/Assets/GoogleMobileAds/Api/AdRequest.cs
index 6191f4015..7df70a666 100644
--- a/source/plugin/Assets/GoogleMobileAds/Api/AdRequest.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Api/AdRequest.cs
@@ -21,7 +21,7 @@ namespace GoogleMobileAds.Api
{
public class AdRequest
{
- public const string Version = "3.10.0";
+ public const string Version = "3.11.0";
public const string TestDeviceSimulator = "SIMULATOR";
private AdRequest(Builder builder)
diff --git a/source/plugin/Assets/GoogleMobileAds/Api/BannerView.cs b/source/plugin/Assets/GoogleMobileAds/Api/BannerView.cs
index d9cf299bc..fa917ea46 100644
--- a/source/plugin/Assets/GoogleMobileAds/Api/BannerView.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Api/BannerView.cs
@@ -34,6 +34,7 @@ public BannerView(string adUnitId, AdSize adSize, AdPosition position)
this.client = (IBannerClient)method.Invoke(null, null);
client.CreateBannerView(adUnitId, adSize, position);
+ Utils.CheckInitialization();
ConfigureBannerEvents();
}
@@ -48,6 +49,7 @@ public BannerView(string adUnitId, AdSize adSize, int x, int y)
this.client = (IBannerClient)method.Invoke(null, null);
client.CreateBannerView(adUnitId, adSize, x, y);
+ Utils.CheckInitialization();
ConfigureBannerEvents();
}
@@ -116,7 +118,7 @@ private void ConfigureBannerEvents()
{
if (this.OnAdLoaded != null)
{
- this.OnAdLoaded(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdLoaded(this, args));
}
};
@@ -124,7 +126,7 @@ private void ConfigureBannerEvents()
{
if (this.OnAdFailedToLoad != null)
{
- this.OnAdFailedToLoad(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdFailedToLoad(this, args));
}
};
@@ -132,7 +134,7 @@ private void ConfigureBannerEvents()
{
if (this.OnAdOpening != null)
{
- this.OnAdOpening(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdOpening(this, args));
}
};
@@ -140,7 +142,7 @@ private void ConfigureBannerEvents()
{
if (this.OnAdClosed != null)
{
- this.OnAdClosed(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdClosed(this, args));
}
};
@@ -148,7 +150,7 @@ private void ConfigureBannerEvents()
{
if (this.OnAdLeavingApplication != null)
{
- this.OnAdLeavingApplication(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdLeavingApplication(this, args));
}
};
}
diff --git a/source/plugin/Assets/GoogleMobileAds/Api/InterstitialAd.cs b/source/plugin/Assets/GoogleMobileAds/Api/InterstitialAd.cs
index 1312a0758..68039c707 100644
--- a/source/plugin/Assets/GoogleMobileAds/Api/InterstitialAd.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Api/InterstitialAd.cs
@@ -34,45 +34,46 @@ public InterstitialAd(string adUnitId)
this.client = (IInterstitialClient)method.Invoke(null, null);
client.CreateInterstitialAd(adUnitId);
+ Utils.CheckInitialization();
this.client.OnAdLoaded += (sender, args) =>
+ {
+ if (this.OnAdLoaded != null)
{
- if(this.OnAdLoaded != null)
- {
- this.OnAdLoaded(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdLoaded(this, args));
+ }
+ };
this.client.OnAdFailedToLoad += (sender, args) =>
+ {
+ if (this.OnAdFailedToLoad != null)
{
- if(this.OnAdFailedToLoad != null)
- {
- this.OnAdFailedToLoad(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdFailedToLoad(this, args));
+ }
+ };
this.client.OnAdOpening += (sender, args) =>
+ {
+ if (this.OnAdOpening != null)
{
- if(this.OnAdOpening != null)
- {
- this.OnAdOpening(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdOpening(this, args));
+ }
+ };
this.client.OnAdClosed += (sender, args) =>
+ {
+ if (this.OnAdClosed != null)
{
- if(this.OnAdClosed != null)
- {
- this.OnAdClosed(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdClosed(this, args));
+ }
+ };
this.client.OnAdLeavingApplication += (sender, args) =>
+ {
+ if (this.OnAdLeavingApplication != null)
{
- if(this.OnAdLeavingApplication != null)
- {
- this.OnAdLeavingApplication(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdLeavingApplication(this, args));
+ }
+ };
}
// These are the ad callback events that can be hooked into.
diff --git a/source/plugin/Assets/GoogleMobileAds/Api/MobileAds.cs b/source/plugin/Assets/GoogleMobileAds/Api/MobileAds.cs
index cdd36254c..16bb4081a 100644
--- a/source/plugin/Assets/GoogleMobileAds/Api/MobileAds.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Api/MobileAds.cs
@@ -26,6 +26,7 @@ public class MobileAds
public static void Initialize(string appId)
{
client.Initialize(appId);
+ MobileAdsEventExecutor.Initialize();
}
public static void SetApplicationMuted(bool muted)
@@ -38,6 +39,11 @@ public static void SetApplicationVolume(float volume)
client.SetApplicationVolume(volume);
}
+ public static void SetiOSAppPauseOnBackground(bool pause)
+ {
+ client.SetiOSAppPauseOnBackground(pause);
+ }
+
private static IMobileAdsClient GetMobileAdsClient()
{
Type googleMobileAdsClientFactory = Type.GetType(
diff --git a/source/plugin/Assets/GoogleMobileAds/Api/NativeExpressAdView.cs b/source/plugin/Assets/GoogleMobileAds/Api/NativeExpressAdView.cs
index f9dc4a8dd..2d6c4c241 100644
--- a/source/plugin/Assets/GoogleMobileAds/Api/NativeExpressAdView.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Api/NativeExpressAdView.cs
@@ -34,6 +34,7 @@ public NativeExpressAdView(string adUnitId, AdSize adSize, AdPosition position)
this.client = (INativeExpressAdClient)method.Invoke(null, null);
this.client.CreateNativeExpressAdView(adUnitId, adSize, position);
+ Utils.CheckInitialization();
ConfigureNativeExpressAdEvents();
}
@@ -48,6 +49,7 @@ public NativeExpressAdView(string adUnitId, AdSize adSize, int x, int y)
this.client = (INativeExpressAdClient)method.Invoke(null, null);
this.client.CreateNativeExpressAdView(adUnitId, adSize, x, y);
+ Utils.CheckInitialization();
ConfigureNativeExpressAdEvents();
}
@@ -90,41 +92,41 @@ private void ConfigureNativeExpressAdEvents()
{
this.client.OnAdLoaded += (sender, args) =>
{
- if(this.OnAdLoaded != null)
+ if (this.OnAdLoaded != null)
{
- this.OnAdLoaded(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdLoaded(this, args));
}
};
this.client.OnAdFailedToLoad += (sender, args) =>
{
- if(this.OnAdFailedToLoad != null)
+ if (this.OnAdFailedToLoad != null)
{
- this.OnAdFailedToLoad(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdFailedToLoad(this, args));
}
};
this.client.OnAdOpening += (sender, args) =>
{
- if(this.OnAdOpening != null)
+ if (this.OnAdOpening != null)
{
- this.OnAdOpening(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdOpening(this, args));
}
};
this.client.OnAdClosed += (sender, args) =>
{
- if(this.OnAdClosed != null)
+ if (this.OnAdClosed != null)
{
- this.OnAdClosed(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdClosed(this, args));
}
};
this.client.OnAdLeavingApplication += (sender, args) =>
{
- if(this.OnAdLeavingApplication != null)
+ if (this.OnAdLeavingApplication != null)
{
- this.OnAdLeavingApplication(this, args);
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdLeavingApplication(this, args));
}
};
}
diff --git a/source/plugin/Assets/GoogleMobileAds/Api/RewardBasedVideoAd.cs b/source/plugin/Assets/GoogleMobileAds/Api/RewardBasedVideoAd.cs
index c31c6df96..9da3064d8 100644
--- a/source/plugin/Assets/GoogleMobileAds/Api/RewardBasedVideoAd.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Api/RewardBasedVideoAd.cs
@@ -43,61 +43,62 @@ private RewardBasedVideoAd()
this.client = (IRewardBasedVideoAdClient)method.Invoke(null, null);
client.CreateRewardBasedVideoAd();
+ Utils.CheckInitialization();
this.client.OnAdLoaded += (sender, args) =>
+ {
+ if (this.OnAdLoaded != null)
{
- if (this.OnAdLoaded != null)
- {
- this.OnAdLoaded(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdLoaded(this, args));
+ }
+ };
this.client.OnAdFailedToLoad += (sender, args) =>
+ {
+ if (this.OnAdFailedToLoad != null)
{
- if (this.OnAdFailedToLoad != null)
- {
- this.OnAdFailedToLoad(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdFailedToLoad(this, args));
+ }
+ };
this.client.OnAdOpening += (sender, args) =>
+ {
+ if (this.OnAdOpening != null)
{
- if (this.OnAdOpening != null)
- {
- this.OnAdOpening(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdOpening(this, args));
+ }
+ };
this.client.OnAdStarted += (sender, args) =>
+ {
+ if (this.OnAdStarted != null)
{
- if (this.OnAdStarted != null)
- {
- this.OnAdStarted(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdStarted(this, args));
+ }
+ };
this.client.OnAdClosed += (sender, args) =>
+ {
+ if (this.OnAdClosed != null)
{
- if (this.OnAdClosed != null)
- {
- this.OnAdClosed(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdClosed(this, args));
+ }
+ };
this.client.OnAdLeavingApplication += (sender, args) =>
+ {
+ if (this.OnAdLeavingApplication != null)
{
- if (this.OnAdLeavingApplication != null)
- {
- this.OnAdLeavingApplication(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdLeavingApplication(this, args));
+ }
+ };
this.client.OnAdRewarded += (sender, args) =>
+ {
+ if (this.OnAdRewarded != null)
{
- if (this.OnAdRewarded != null)
- {
- this.OnAdRewarded(this, args);
- }
- };
+ MobileAdsEventExecutor.executeInUpdate(() => this.OnAdRewarded(this, args));
+ }
+ };
}
// These are the ad callback events that can be hooked into.
diff --git a/source/plugin/Assets/GoogleMobileAds/Common/DummyClient.cs b/source/plugin/Assets/GoogleMobileAds/Common/DummyClient.cs
index 63da6acfc..b1d084354 100644
--- a/source/plugin/Assets/GoogleMobileAds/Common/DummyClient.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Common/DummyClient.cs
@@ -29,7 +29,7 @@ public DummyClient()
}
// Disable warnings for unused dummy ad events.
- #pragma warning disable 67
+#pragma warning disable 67
public event EventHandler OnAdLoaded;
@@ -47,7 +47,7 @@ public DummyClient()
public event EventHandler OnCustomNativeTemplateAdLoaded;
- #pragma warning restore 67
+#pragma warning restore 67
public string UserId
{
@@ -78,6 +78,11 @@ public void SetApplicationVolume(float volume)
Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name);
}
+ public void SetiOSAppPauseOnBackground(bool pause)
+ {
+ Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name);
+ }
+
public void CreateBannerView(string adUnitId, AdSize adSize, AdPosition position)
{
Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name);
diff --git a/source/plugin/Assets/GoogleMobileAds/Common/IMobileAdsClient.cs b/source/plugin/Assets/GoogleMobileAds/Common/IMobileAdsClient.cs
index 1f6226869..b808e0222 100644
--- a/source/plugin/Assets/GoogleMobileAds/Common/IMobileAdsClient.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Common/IMobileAdsClient.cs
@@ -29,5 +29,8 @@ public interface IMobileAdsClient
// all ads. Use this method only if your application has its own volume controls
// (e.g., custom music or sound effect muting). Defaults to false.
void SetApplicationMuted(bool muted);
+
+ // Set whether an iOS app should pause when a full screen ad is displayed.
+ void SetiOSAppPauseOnBackground(bool pause);
}
}
diff --git a/source/plugin/Assets/GoogleMobileAds/Common/MobileAdsEventExecutor.cs b/source/plugin/Assets/GoogleMobileAds/Common/MobileAdsEventExecutor.cs
new file mode 100644
index 000000000..54baa03fe
--- /dev/null
+++ b/source/plugin/Assets/GoogleMobileAds/Common/MobileAdsEventExecutor.cs
@@ -0,0 +1,91 @@
+// Copyright (C) 2018 Google, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using UnityEngine;
+
+namespace GoogleMobileAds.Common
+{
+ internal class MobileAdsEventExecutor : MonoBehaviour
+ {
+ private static MobileAdsEventExecutor instance = null;
+
+ private static List adEventsQueue = new List();
+
+ private volatile static bool adEventsQueueEmpty = true;
+
+ public static void Initialize()
+ {
+ if (IsActive())
+ {
+ return;
+ }
+
+ // Add an invisible game object to the scene
+ GameObject obj = new GameObject("MobileAdsMainThreadExecuter");
+ obj.hideFlags = HideFlags.HideAndDontSave;
+ DontDestroyOnLoad(obj);
+ instance = obj.AddComponent();
+ }
+
+ public static bool IsActive()
+ {
+ return instance != null;
+ }
+
+ public void Awake()
+ {
+ DontDestroyOnLoad(gameObject);
+ }
+
+ public static void executeInUpdate(Action action)
+ {
+ lock (adEventsQueue)
+ {
+ adEventsQueue.Add(action);
+ adEventsQueueEmpty = false;
+ }
+ }
+
+ public void Update()
+ {
+ if (adEventsQueueEmpty)
+ {
+ return;
+ }
+
+ List stagedAdEventsQueue = new List();
+
+ lock (adEventsQueue)
+ {
+ stagedAdEventsQueue.AddRange(adEventsQueue);
+ adEventsQueue.Clear();
+ adEventsQueueEmpty = true;
+ }
+
+ foreach (Action stagedEvent in stagedAdEventsQueue)
+ {
+ stagedEvent.Invoke();
+ }
+ }
+
+ public void OnDisable()
+ {
+ instance = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/plugin/Assets/GoogleMobileAds/Common/MobileAdsEventExecutor.cs.meta b/source/plugin/Assets/GoogleMobileAds/Common/MobileAdsEventExecutor.cs.meta
new file mode 100644
index 000000000..ec47570a1
--- /dev/null
+++ b/source/plugin/Assets/GoogleMobileAds/Common/MobileAdsEventExecutor.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: d5dfa1423353e45c9bb636c123e5a05a
+timeCreated: 1517530267
+licenseType: Pro
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/source/plugin/Assets/GoogleMobileAds/Common/Utils.cs b/source/plugin/Assets/GoogleMobileAds/Common/Utils.cs
index a0cf70c81..a9730554c 100644
--- a/source/plugin/Assets/GoogleMobileAds/Common/Utils.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Common/Utils.cs
@@ -21,6 +21,17 @@ namespace GoogleMobileAds.Common
{
internal class Utils
{
+ public static void CheckInitialization()
+ {
+ if (!MobileAdsEventExecutor.IsActive())
+ {
+ Debug.Log("You intitialized an ad object but have not yet called MobileAds.Initialize(). We " +
+ "highly recommend you call MobileAds.Initialize() before interacting with the Google " +
+ "Mobile Ads SDK.");
+ }
+ MobileAdsEventExecutor.Initialize();
+ }
+
public static Texture2D GetTexture2DFromByteArray(byte[] img)
{
// Create a texture. Texture size does not matter, since
diff --git a/source/plugin/Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml b/source/plugin/Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml
index d1434da53..97438d585 100644
--- a/source/plugin/Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml
+++ b/source/plugin/Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml
@@ -1,6 +1,6 @@
-
+
https://maven.google.com
diff --git a/source/plugin/Assets/GoogleMobileAds/Platforms/Android/AdLoaderClient.cs b/source/plugin/Assets/GoogleMobileAds/Platforms/Android/AdLoaderClient.cs
index d491ce340..f0355add8 100644
--- a/source/plugin/Assets/GoogleMobileAds/Platforms/Android/AdLoaderClient.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Platforms/Android/AdLoaderClient.cs
@@ -84,7 +84,8 @@ public void onCustomClick(AndroidJavaObject ad, string assetName)
{
CustomNativeTemplateAd nativeAd = new CustomNativeTemplateAd(
new CustomNativeTemplateClient(ad));
- this.CustomNativeTemplateCallbacks[nativeAd.GetCustomTemplateId()](nativeAd, assetName);
+ MobileAdsEventExecutor.executeInUpdate(() =>
+ this.CustomNativeTemplateCallbacks[nativeAd.GetCustomTemplateId()](nativeAd, assetName));
}
}
}
diff --git a/source/plugin/Assets/GoogleMobileAds/Platforms/Android/MobileAdsClient.cs b/source/plugin/Assets/GoogleMobileAds/Platforms/Android/MobileAdsClient.cs
index 0b229db05..392fe8355 100644
--- a/source/plugin/Assets/GoogleMobileAds/Platforms/Android/MobileAdsClient.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Platforms/Android/MobileAdsClient.cs
@@ -54,6 +54,11 @@ public void SetApplicationMuted(bool muted)
AndroidJavaClass mobileAdsClass = new AndroidJavaClass(Utils.MobileAdsClassName);
mobileAdsClass.CallStatic("setAppMuted", muted);
}
+
+ public void SetiOSAppPauseOnBackground(bool pause)
+ {
+ // Do nothing on Android. Default behavior is to pause when app is backgrounded.
+ }
}
}
diff --git a/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/CustomNativeTemplateClient.cs b/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/CustomNativeTemplateClient.cs
index 862e6c37f..67d0e9887 100644
--- a/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/CustomNativeTemplateClient.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/CustomNativeTemplateClient.cs
@@ -145,7 +145,7 @@ private static void NativeCustomTemplateDidReceiveClickCallback(
if (client.clickHandler != null)
{
CustomNativeTemplateAd nativeAd = new CustomNativeTemplateAd(client);
- client.clickHandler(nativeAd, assetName);
+ MobileAdsEventExecutor.executeInUpdate(() => client.clickHandler(nativeAd, assetName));
}
}
diff --git a/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/Externs.cs b/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/Externs.cs
index 8b0fc5cfa..35f650b22 100644
--- a/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/Externs.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/Externs.cs
@@ -33,6 +33,9 @@ internal class Externs
[DllImport("__Internal")]
internal static extern void GADUSetApplicationMuted(bool muted);
+ [DllImport("__Internal")]
+ internal static extern void GADUSetiOSAppPauseOnBackground(bool pause);
+
[DllImport("__Internal")]
internal static extern IntPtr GADUCreateRequest();
diff --git a/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/MobileAdsClient.cs b/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/MobileAdsClient.cs
index 9e3182ec4..6d9085f90 100644
--- a/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/MobileAdsClient.cs
+++ b/source/plugin/Assets/GoogleMobileAds/Platforms/iOS/MobileAdsClient.cs
@@ -48,6 +48,11 @@ public void SetApplicationMuted(bool muted)
{
Externs.GADUSetApplicationMuted(muted);
}
+
+ public void SetiOSAppPauseOnBackground(bool pause)
+ {
+ Externs.GADUSetiOSAppPauseOnBackground(pause);
+ }
}
}
diff --git a/source/plugin/Assets/Plugins/iOS/GADUInterface.m b/source/plugin/Assets/Plugins/iOS/GADUInterface.m
index da629b54d..884e7ecf3 100644
--- a/source/plugin/Assets/Plugins/iOS/GADUInterface.m
+++ b/source/plugin/Assets/Plugins/iOS/GADUInterface.m
@@ -4,6 +4,7 @@
#import "GADUBanner.h"
#import "GADUInterstitial.h"
#import "GADUNativeCustomTemplateAd.h"
+#import "GADUPluginUtil.h"
#import "GADUAdNetworkExtras.h"
#import "GADUNativeExpressAd.h"
#import "GADUObjectCache.h"
@@ -66,6 +67,10 @@ void GADUSetApplicationMuted(BOOL muted) {
[[GADMobileAds sharedInstance] setApplicationMuted:muted];
}
+// Indicates if the Unity app should be paused when a full screen ad (interstitial
+// or rewarded video ad) is displayed.
+void GADUSetiOSAppPauseOnBackground(BOOL pause) { [GADUPluginUtil setPauseOnBackground:pause]; }
+
/// Creates a GADBannerView with the specified width, height, and position. Returns a reference to
/// the GADUBannerView.
GADUTypeBannerRef GADUCreateBannerView(GADUTypeBannerClientRef *bannerClient, const char *adUnitID,
@@ -510,7 +515,7 @@ void GADURequestNativeAd(GADUTypeAdLoaderRef adLoader, GADUTypeRequestRef reques
(__bridge GADUNativeCustomTemplateAd *)nativeCustomTemplateAd;
NSData *imageData = UIImageJPEGRepresentation(
[internalNativeCustomTemplateAd imageForKey:GADUStringFromUTF8String(key)], 0.0);
- NSString *base64String = [imageData base64Encoding];
+ NSString *base64String = [imageData base64EncodedStringWithOptions:nil];
return cStringCopy(base64String.UTF8String);
}
diff --git a/source/plugin/Assets/Plugins/iOS/GADUInterstitial.m b/source/plugin/Assets/Plugins/iOS/GADUInterstitial.m
index 0a8bed275..5e98a1946 100644
--- a/source/plugin/Assets/Plugins/iOS/GADUInterstitial.m
+++ b/source/plugin/Assets/Plugins/iOS/GADUInterstitial.m
@@ -66,6 +66,10 @@ - (void)interstitial:(GADInterstitial *)ad didFailToReceiveAdWithError:(GADReque
}
- (void)interstitialWillPresentScreen:(GADInterstitial *)ad {
+ if ([GADUPluginUtil pauseOnBackground]) {
+ UnityPause(YES);
+ }
+
if (self.willPresentCallback) {
self.willPresentCallback(self.interstitialClient);
}
@@ -76,6 +80,10 @@ - (void)interstitialWillDismissScreen:(GADInterstitial *)ad {
}
- (void)interstitialDidDismissScreen:(GADInterstitial *)ad {
+ if (UnityIsPaused()) {
+ UnityPause(NO);
+ }
+
if (self.didDismissCallback) {
self.didDismissCallback(self.interstitialClient);
}
diff --git a/source/plugin/Assets/Plugins/iOS/GADUNativeCustomTemplateAd.m b/source/plugin/Assets/Plugins/iOS/GADUNativeCustomTemplateAd.m
index 37c537059..2b2cbdd0e 100644
--- a/source/plugin/Assets/Plugins/iOS/GADUNativeCustomTemplateAd.m
+++ b/source/plugin/Assets/Plugins/iOS/GADUNativeCustomTemplateAd.m
@@ -25,13 +25,13 @@ - (UIImage *)imageForKey:(NSString *)key {
}
- (void)performClickOnAssetWithKey:(NSString *)key withCustomClickAction:(bool)customClickAction {
- dispatch_block_t clickHandler = nil;
if (customClickAction) {
- clickHandler = ^{
- [self didReceiveClickForAsset:key];
- };
+ __weak GADUNativeCustomTemplateAd *weakSelf = self;
+ [self.nativeCustomTemplateAd setCustomClickHandler:^(NSString *assetID){
+ [weakSelf didReceiveClickForAsset:key];
+ }];
}
- [self.nativeCustomTemplateAd performClickOnAssetWithKey:key customClickHandler:clickHandler];
+ [self.nativeCustomTemplateAd performClickOnAssetWithKey:key];
}
- (void)didReceiveClickForAsset:(NSString *)key {
diff --git a/source/plugin/Assets/Plugins/iOS/GADUPluginUtil.h b/source/plugin/Assets/Plugins/iOS/GADUPluginUtil.h
index c3361b2e4..b96602ce2 100644
--- a/source/plugin/Assets/Plugins/iOS/GADUPluginUtil.h
+++ b/source/plugin/Assets/Plugins/iOS/GADUPluginUtil.h
@@ -8,6 +8,9 @@
@interface GADUPluginUtil : NSObject
+/// Whether the Unity app should be paused when a full screen ad is displayed.
+@property(class) BOOL pauseOnBackground;
+
/// Returns the Unity view controller.
+ (UIViewController *)unityGLViewController;
diff --git a/source/plugin/Assets/Plugins/iOS/GADUPluginUtil.m b/source/plugin/Assets/Plugins/iOS/GADUPluginUtil.m
index d15419dcb..a1aefb6dc 100644
--- a/source/plugin/Assets/Plugins/iOS/GADUPluginUtil.m
+++ b/source/plugin/Assets/Plugins/iOS/GADUPluginUtil.m
@@ -33,6 +33,16 @@ static CGFloat FullSafeWidthLandscape(void) {
@implementation GADUPluginUtil
+static BOOL _pauseOnBackground = NO;
+
++ (BOOL)pauseOnBackground {
+ return _pauseOnBackground;
+}
+
++ (void)setPauseOnBackground:(BOOL)pause {
+ _pauseOnBackground = pause;
+}
+
+ (GADAdSize)safeAdSizeForAdSize:(GADAdSize)adSize {
if (IsOperatingSystemAtLeastVersion(11) &&
GADAdSizeEqualToSize(kGADAdSizeSmartBannerLandscape, adSize)) {
diff --git a/source/plugin/Assets/Plugins/iOS/GADURewardBasedVideoAd.m b/source/plugin/Assets/Plugins/iOS/GADURewardBasedVideoAd.m
index c65b54415..418bc8b59 100644
--- a/source/plugin/Assets/Plugins/iOS/GADURewardBasedVideoAd.m
+++ b/source/plugin/Assets/Plugins/iOS/GADURewardBasedVideoAd.m
@@ -19,7 +19,7 @@ + (UIViewController *)unityGLViewController {
}
- (instancetype)initWithRewardBasedVideoClientReference:
- (GADUTypeRewardBasedVideoAdClientRef *)rewardBasedVideoAdClient {
+ (GADUTypeRewardBasedVideoAdClientRef *)rewardBasedVideoAdClient {
self = [super init];
if (self) {
_rewardBasedVideoAdClient = rewardBasedVideoAdClient;
@@ -72,6 +72,10 @@ - (void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd
}
- (void)rewardBasedVideoAdDidOpen:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
+ if ([GADUPluginUtil pauseOnBackground]) {
+ UnityPause(YES);
+ }
+
if (self.didOpenCallback) {
self.didOpenCallback(self.rewardBasedVideoAdClient);
}
@@ -84,6 +88,10 @@ - (void)rewardBasedVideoAdDidStartPlaying:(GADRewardBasedVideoAd *)rewardBasedVi
}
- (void)rewardBasedVideoAdDidClose:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
+ if (UnityIsPaused()) {
+ UnityPause(NO);
+ }
+
if (self.didCloseCallback) {
self.didCloseCallback(self.rewardBasedVideoAdClient);
}