No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ManifestProcessor.cs 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // Copyright (C) 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #if UNITY_ANDROID
  15. using System.Collections.Generic;
  16. using System.IO;
  17. using System.Linq;
  18. using System.Xml.Linq;
  19. using UnityEditor;
  20. using UnityEditor.Build;
  21. #if UNITY_2018_1_OR_NEWER
  22. using UnityEditor.Build.Reporting;
  23. #endif
  24. using UnityEngine;
  25. using GoogleMobileAds.Editor;
  26. #if UNITY_2018_1_OR_NEWER
  27. public class ManifestProcessor : IPreprocessBuildWithReport
  28. #else
  29. public class ManifestProcessor : IPreprocessBuild
  30. #endif
  31. {
  32. private const string MANIFEST_RELATIVE_PATH =
  33. "Plugins/Android/GoogleMobileAdsPlugin.androidlib/AndroidManifest.xml";
  34. private const string PROPERTIES_RELATIVE_PATH =
  35. "Plugins/Android/GoogleMobileAdsPlugin.androidlib/project.properties";
  36. private const string METADATA_APPLICATION_ID =
  37. "com.google.android.gms.ads.APPLICATION_ID";
  38. private const string METADATA_DELAY_APP_MEASUREMENT_INIT =
  39. "com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT";
  40. private const string METADATA_OPTIMIZE_INITIALIZATION =
  41. "com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION";
  42. private const string METADATA_OPTIMIZE_AD_LOADING =
  43. "com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING";
  44. // LINT.IfChange
  45. private const string METADATA_UNITY_VERSION = "com.google.unity.ads.UNITY_VERSION";
  46. // LINT.ThenChange(//depot/google3/javatests/com/google/android/gmscore/integ/modules/admob/tests/robolectric/src/com/google/android/gms/ads/nonagon/signals/StaticDeviceSignalSourceTest.java)
  47. private XNamespace ns = "http://schemas.android.com/apk/res/android";
  48. public int callbackOrder { get { return 0; } }
  49. #if UNITY_2018_1_OR_NEWER
  50. public void OnPreprocessBuild(BuildReport report)
  51. #else
  52. public void OnPreprocessBuild(BuildTarget target, string path)
  53. #endif
  54. {
  55. string manifestPath = Path.Combine(Application.dataPath, MANIFEST_RELATIVE_PATH);
  56. string propertiesPath = Path.Combine(Application.dataPath, PROPERTIES_RELATIVE_PATH);
  57. /*
  58. * Handle importing GMA via Unity Package Manager.
  59. */
  60. EditorPathUtils pathUtils =
  61. ScriptableObject.CreateInstance<EditorPathUtils>();
  62. if (pathUtils.IsPackageRootPath())
  63. {
  64. // pathUtils.GetParentDirectoryAssetPath() returns "Packages/.../GoogleMobileAds" but
  65. // Plugins is at the same level of GoogleMobileAds so we go up one directory before
  66. // appending MANIFEST_RELATIVE_PATH.
  67. string packagesPathPrefix =
  68. Path.GetDirectoryName(pathUtils.GetParentDirectoryAssetPath());
  69. manifestPath = Path.Combine(packagesPathPrefix, MANIFEST_RELATIVE_PATH);
  70. propertiesPath = Path.Combine(packagesPathPrefix, PROPERTIES_RELATIVE_PATH);
  71. }
  72. if (AssetDatabase.IsValidFolder("Packages/com.google.ads.mobile"))
  73. {
  74. manifestPath = Path.Combine("Packages/com.google.ads.mobile", MANIFEST_RELATIVE_PATH);
  75. }
  76. XDocument manifest = null;
  77. try
  78. {
  79. manifest = XDocument.Load(manifestPath);
  80. }
  81. #pragma warning disable 0168
  82. catch (IOException e)
  83. #pragma warning restore 0168
  84. {
  85. StopBuildWithMessage("AndroidManifest.xml is missing. Try re-importing the plugin.");
  86. }
  87. XElement elemManifest = manifest.Element("manifest");
  88. if (elemManifest == null)
  89. {
  90. StopBuildWithMessage("AndroidManifest.xml is not valid. Try re-importing the plugin.");
  91. }
  92. XElement elemApplication = elemManifest.Element("application");
  93. if (elemApplication == null)
  94. {
  95. StopBuildWithMessage("AndroidManifest.xml is not valid. Try re-importing the plugin.");
  96. }
  97. GoogleMobileAdsSettings instance = GoogleMobileAdsSettings.LoadInstance();
  98. string appId = instance.GoogleMobileAdsAndroidAppId;
  99. if (appId.Length == 0)
  100. {
  101. StopBuildWithMessage(
  102. "Android Google Mobile Ads app ID is empty. Please enter a valid app ID to run ads properly.");
  103. }
  104. IEnumerable<XElement> metas = elemApplication.Descendants()
  105. .Where( elem => elem.Name.LocalName.Equals("meta-data"));
  106. SetMetadataElement(elemApplication,
  107. metas,
  108. METADATA_APPLICATION_ID,
  109. appId);
  110. SetMetadataElement(elemApplication,
  111. metas,
  112. METADATA_DELAY_APP_MEASUREMENT_INIT,
  113. instance.DelayAppMeasurementInit);
  114. SetMetadataElement(elemApplication,
  115. metas,
  116. METADATA_OPTIMIZE_INITIALIZATION,
  117. instance.OptimizeInitialization);
  118. SetMetadataElement(elemApplication,
  119. metas,
  120. METADATA_OPTIMIZE_AD_LOADING,
  121. instance.OptimizeAdLoading);
  122. SetMetadataElement(elemApplication,
  123. metas,
  124. METADATA_UNITY_VERSION,
  125. Application.unityVersion);
  126. elemManifest.Save(manifestPath);
  127. }
  128. private XElement CreateMetaElement(string name, object value)
  129. {
  130. return new XElement("meta-data",
  131. new XAttribute(ns + "name", name), new XAttribute(ns + "value", value));
  132. }
  133. private XElement GetMetaElement(IEnumerable<XElement> metas, string metaName)
  134. {
  135. foreach (XElement elem in metas)
  136. {
  137. IEnumerable<XAttribute> attrs = elem.Attributes();
  138. foreach (XAttribute attr in attrs)
  139. {
  140. if (attr.Name.Namespace.Equals(ns)
  141. && attr.Name.LocalName.Equals("name") && attr.Value.Equals(metaName))
  142. {
  143. return elem;
  144. }
  145. }
  146. }
  147. return null;
  148. }
  149. /// <summary>
  150. /// Utility for setting a metadata element
  151. /// </summary>
  152. /// <param name="elemApplication">application element</param>
  153. /// <param name="metas">all metadata elements</param>
  154. /// <param name="metadataName">name of the element to set</param>
  155. /// <param name="metadataValue">value to set</param>
  156. private void SetMetadataElement(XElement elemApplication,
  157. IEnumerable<XElement> metas,
  158. string metadataName,
  159. string metadataValue)
  160. {
  161. XElement element = GetMetaElement(metas, metadataName);
  162. if (element == null)
  163. {
  164. elemApplication.Add(CreateMetaElement(metadataName, metadataValue));
  165. }
  166. else
  167. {
  168. element.SetAttributeValue(ns + "value", metadataValue);
  169. }
  170. }
  171. /// <summary>
  172. /// Utility for setting a metadata element
  173. /// </summary>
  174. /// <param name="elemApplication">application element</param>
  175. /// <param name="metas">all metadata elements</param>
  176. /// <param name="metadataName">name of the element to set</param>
  177. /// <param name="metadataValue">value to set</param>
  178. /// <param name="defaultValue">If metadataValue is default, node will be removed.</param>
  179. private void SetMetadataElement(XElement elemApplication,
  180. IEnumerable<XElement> metas,
  181. string metadataName,
  182. bool metadataValue,
  183. bool defaultValue = false)
  184. {
  185. XElement element = GetMetaElement(metas, metadataName);
  186. if (metadataValue != defaultValue)
  187. {
  188. if (element == null)
  189. {
  190. elemApplication.Add(CreateMetaElement(metadataName, metadataValue));
  191. }
  192. else
  193. {
  194. element.SetAttributeValue(ns + "value", metadataValue);
  195. }
  196. }
  197. else
  198. {
  199. if (element != null)
  200. {
  201. element.Remove();
  202. }
  203. }
  204. }
  205. private void StopBuildWithMessage(string message)
  206. {
  207. string prefix = "[GoogleMobileAds] ";
  208. #if UNITY_2017_1_OR_NEWER
  209. throw new BuildPlayerWindow.BuildMethodException(prefix + message);
  210. #else
  211. throw new OperationCanceledException(prefix + message);
  212. #endif
  213. }
  214. }
  215. #endif