using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Linq; using UnityEditor; namespace Azerion.BlueStack.Editor.Android { public class ManifestProcessor { private const string MANIFEST_FILE_PATH = "Assets/Plugins/Android/AndroidManifest.xml"; public const string MANIFEST_FILE_MISSING = MANIFEST_FILE_PATH + " is missing. Please add `Custom Main Manifest` for android via `Project Settings -> Player -> Publish Settings`."; public const string INVALID_MANIFEST_FILE = "AndroidManifest.xml is not valid. Try re-importing the plugin."; public const string APPLICATION_TAG_MISSING = "AndroidManifest.xml is not valid. Application tag is missing. Try re-importing the plugin."; public const string APP_IDS_MISSING = "AdMob app id is missing. Please provide the AdMob app id via Azerion > BlueStack > Settings"; private const string META_ADMOB_APP_ID = "com.google.android.gms.ads.APPLICATION_ID"; private XNamespace ANDROID_NS = "http://schemas.android.com/apk/res/android"; public static ManifestProcessor Instance { get; } = new ManifestProcessor(); public void process(string path) { string manifestPath = Path.GetFullPath(path); XDocument manifest = null; try { manifest = XDocument.Load(manifestPath); } catch (IOException e) { StopBuildWithMessage(MANIFEST_FILE_MISSING +" : " + e.Message ); } XElement elemManifest = manifest.Element("manifest"); if (elemManifest == null) { StopBuildWithMessage(INVALID_MANIFEST_FILE); } XElement elemApplication = elemManifest.Element("application"); if (elemApplication == null) { StopBuildWithMessage(APPLICATION_TAG_MISSING); } if (string.IsNullOrEmpty(BlueStackSettings.Instance.AdmobAppIdAndroid)) { StopBuildWithMessage(APP_IDS_MISSING); } IEnumerable metas = elemApplication.Descendants() .Where(elem => elem.Name.LocalName.Equals("meta-data")); XElement adMobAppMetaElement = GetMetaElement(metas, META_ADMOB_APP_ID); if (adMobAppMetaElement == null) { elemApplication.Add(CreateMetaElement(META_ADMOB_APP_ID, BlueStackSettings.Instance.AdmobAppIdAndroid)); } else { adMobAppMetaElement.SetAttributeValue(ANDROID_NS + "value", BlueStackSettings.Instance.AdmobAppIdAndroid); } elemManifest.Save(manifestPath); } private XElement CreateMetaElement(string name, object value) { return new XElement("meta-data", new XAttribute(ANDROID_NS + "name", name), new XAttribute(ANDROID_NS + "value", value)); } private XElement GetMetaElement(IEnumerable metas, string metaName) { foreach (XElement elem in metas) { IEnumerable attrs = elem.Attributes(); foreach (XAttribute attr in attrs) { if (attr.Name.Namespace.Equals(ANDROID_NS) && attr.Name.LocalName.Equals("name") && attr.Value.Equals(metaName)) { return elem; } } } return null; } private void StopBuildWithMessage(string message) { string prefix = "[BlueStack] "; #if UNITY_2017_1_OR_NEWER throw new BuildPlayerWindow.BuildMethodException(prefix + message); #else throw new OperationCanceledException(prefix + message); #endif } } }