AndroidManifest.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited.All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. namespace NRKernal
  10. {
  11. using System.Text;
  12. using System.Xml;
  13. /// <summary> An android XML document. </summary>
  14. internal class AndroidXmlDocument : XmlDocument
  15. {
  16. /// <summary> Full pathname of the file. </summary>
  17. protected string m_Path;
  18. /// <summary> Manager for name space. </summary>
  19. protected XmlNamespaceManager nameSpaceManager;
  20. /// <summary> The android XML namespace. </summary>
  21. public readonly string AndroidXmlNamespace = "http://schemas.android.com/apk/res/android";
  22. /// <summary> The android tools XML namespace. </summary>
  23. public readonly string AndroidToolsXmlNamespace = "http://schemas.android.com/tools";
  24. /// <summary> Constructor. </summary>
  25. /// <param name="path"> Full pathname of the file.</param>
  26. public AndroidXmlDocument(string path)
  27. {
  28. m_Path = path;
  29. using (var reader = new XmlTextReader(m_Path))
  30. {
  31. reader.Read();
  32. Load(reader);
  33. }
  34. nameSpaceManager = new XmlNamespaceManager(NameTable);
  35. nameSpaceManager.AddNamespace("android", AndroidXmlNamespace);
  36. }
  37. /// <summary> Gets the save. </summary>
  38. /// <returns> A string. </returns>
  39. public string Save()
  40. {
  41. return SaveAs(m_Path);
  42. }
  43. /// <summary> Saves as. </summary>
  44. /// <param name="path"> Full pathname of the file.</param>
  45. /// <returns> A string. </returns>
  46. public string SaveAs(string path)
  47. {
  48. using (var writer = new XmlTextWriter(path, new UTF8Encoding(false)))
  49. {
  50. writer.Formatting = Formatting.Indented;
  51. Save(writer);
  52. }
  53. return path;
  54. }
  55. }
  56. /// <summary> A list of the android. </summary>
  57. internal class AndroidManifest : AndroidXmlDocument
  58. {
  59. /// <summary> Element describing the application. </summary>
  60. private readonly XmlElement ApplicationElement;
  61. /// <summary> Constructor. </summary>
  62. /// <param name="path"> Full pathname of the file.</param>
  63. public AndroidManifest(string path) : base(path)
  64. {
  65. ApplicationElement = SelectSingleNode("/manifest/application") as XmlElement;
  66. }
  67. /// <summary> Creates android attribute. </summary>
  68. /// <param name="key"> The key.</param>
  69. /// <param name="value"> The value.</param>
  70. /// <param name="name"> (Optional) The name.</param>
  71. /// <returns> The new android attribute. </returns>
  72. private XmlAttribute CreateAndroidAttribute(string key, string value, string name = "android")
  73. {
  74. XmlAttribute attr;
  75. if (name.Equals("tools"))
  76. {
  77. attr = CreateAttribute(name, key, AndroidToolsXmlNamespace);
  78. attr.Value = value;
  79. }
  80. else
  81. {
  82. attr = CreateAttribute(name, key, AndroidXmlNamespace);
  83. attr.Value = value;
  84. }
  85. return attr;
  86. }
  87. /// <summary> Gets activity with launch intent. </summary>
  88. /// <returns> The activity with launch intent. </returns>
  89. internal XmlNode GetActivityWithLaunchIntent()
  90. {
  91. return SelectSingleNode("/manifest/application/activity[intent-filter/action/@android:name='android.intent.action.MAIN' and " +
  92. "intent-filter/category/@android:name='android.intent.category.LAUNCHER']", nameSpaceManager);
  93. }
  94. /// <summary> Gets activity with information intent. </summary>
  95. /// <returns> The activity with information intent. </returns>
  96. internal XmlNode GetActivityWithInfoIntent()
  97. {
  98. return SelectSingleNode("/manifest/application/activity[intent-filter/action/@android:name='android.intent.action.MAIN' and " +
  99. "intent-filter/category/@android:name='android.intent.category.INFO']", nameSpaceManager);
  100. }
  101. /// <summary> Sets external storage. </summary>
  102. /// <param name="flag"> True to flag.</param>
  103. internal void SetExternalStorage(bool flag)
  104. {
  105. var activity = SelectSingleNode("/manifest/application");
  106. var rightapplicationData = SelectSingleNode("/manifest/application[@android:requestLegacyExternalStorage='true']", nameSpaceManager);
  107. if (flag)
  108. {
  109. if (rightapplicationData == null)
  110. {
  111. XmlAttribute newAttribute = CreateAndroidAttribute("requestLegacyExternalStorage", "true");
  112. activity.Attributes.Append(newAttribute);
  113. }
  114. }
  115. else
  116. {
  117. if (rightapplicationData != null)
  118. {
  119. activity.Attributes.RemoveNamedItem("android:requestLegacyExternalStorage");
  120. }
  121. }
  122. }
  123. /// <summary> Sets camera permission. </summary>
  124. internal void SetCameraPermission()
  125. {
  126. var manifest = SelectSingleNode("/manifest");
  127. if (!manifest.InnerXml.Contains("android.permission.CAMERA"))
  128. {
  129. XmlElement child = CreateElement("uses-permission");
  130. manifest.AppendChild(child);
  131. XmlAttribute newAttribute = CreateAndroidAttribute("name", "android.permission.CAMERA");
  132. child.Attributes.Append(newAttribute);
  133. }
  134. //else
  135. //{
  136. // NRDebugger.Info("Already has the camera permission.");
  137. //}
  138. }
  139. internal void SetPackageReadPermission()
  140. {
  141. var manifest = SelectSingleNode("/manifest");
  142. if (!manifest.InnerXml.Contains("android.permission.QUERY_ALL_PACKAGES"))
  143. {
  144. XmlElement child = CreateElement("uses-permission");
  145. manifest.AppendChild(child);
  146. XmlAttribute newAttribute = CreateAndroidAttribute("name", "android.permission.QUERY_ALL_PACKAGES");
  147. child.Attributes.Append(newAttribute);
  148. }
  149. //else
  150. //{
  151. // NRDebugger.Info("Already has the permission of 'android.permission.QUERY_ALL_PACKAGES'.");
  152. //}
  153. }
  154. /// <summary> Sets blue tooth permission. </summary>
  155. internal void SetBlueToothPermission()
  156. {
  157. var manifest = SelectSingleNode("/manifest");
  158. if (!manifest.InnerXml.Contains("android.permission.BLUETOOTH"))
  159. {
  160. XmlElement child = CreateElement("uses-permission");
  161. manifest.AppendChild(child);
  162. XmlAttribute newAttribute = CreateAndroidAttribute("name", "android.permission.BLUETOOTH");
  163. child.Attributes.Append(newAttribute);
  164. // newAttribute = CreateAndroidAttribute("name", "android.permission.BLUETOOTH_ADMIN");
  165. // child.Attributes.Append(newAttribute);
  166. }
  167. //else
  168. //{
  169. // NRDebugger.Info("Already has the bluetooth permission.");
  170. //}
  171. }
  172. internal void SetAudioRecordPermission()
  173. {
  174. var manifest = SelectSingleNode("/manifest");
  175. if (!manifest.InnerXml.Contains("android.permission.RECORD_AUDIO"))
  176. {
  177. XmlElement child = CreateElement("uses-permission");
  178. manifest.AppendChild(child);
  179. XmlAttribute newAttribute = CreateAndroidAttribute("name", "android.permission.RECORD_AUDIO");
  180. child.Attributes.Append(newAttribute);
  181. }
  182. }
  183. /// <summary> Sets sdk meta data. </summary>
  184. internal void SetSDKMetaData()
  185. {
  186. var activity = SelectSingleNode("/manifest/application");
  187. // metadata for "nreal_sdk
  188. var newMetaNRSDK = SelectSingleNode("/manifest/application/meta-data[@android:name='nreal_sdk' and " +
  189. "@android:value='true']", nameSpaceManager);
  190. var oldMetaNRSDK = SelectSingleNode("/manifest/application/meta-data[@android:name='nreal_sdk']", nameSpaceManager);
  191. if (newMetaNRSDK == null)
  192. {
  193. if (oldMetaNRSDK != null)
  194. {
  195. activity.RemoveChild(oldMetaNRSDK);
  196. }
  197. XmlElement child = CreateElement("meta-data");
  198. activity.AppendChild(child);
  199. XmlAttribute newAttribute = CreateAndroidAttribute("name", "nreal_sdk");
  200. child.Attributes.Append(newAttribute);
  201. newAttribute = CreateAndroidAttribute("value", "true");
  202. child.Attributes.Append(newAttribute);
  203. }
  204. // metadata for "com.nreal.supportDevices"
  205. string supportDevices = NRProjectConfigHelper.GetProjectConfig().GetTargetDeviceTypesDesc();
  206. var newMetaDevices = SelectSingleNode("/manifest/application/meta-data[@android:name='com.nreal.supportDevices' and " +
  207. "@android:value='']", nameSpaceManager);
  208. var oldMetaDevices = SelectSingleNode("/manifest/application/meta-data[@android:name='com.nreal.supportDevices']", nameSpaceManager);
  209. if (oldMetaDevices != null)
  210. activity.RemoveChild(oldMetaDevices);
  211. if (newMetaDevices == null)
  212. {
  213. XmlElement child = CreateElement("meta-data");
  214. activity.AppendChild(child);
  215. XmlAttribute newAttribute = CreateAndroidAttribute("name", "com.nreal.supportDevices");
  216. child.Attributes.Append(newAttribute);
  217. newAttribute = CreateAndroidAttribute("value", supportDevices);
  218. child.Attributes.Append(newAttribute);
  219. }
  220. }
  221. /// <summary> Sets a pk displayed on launcher. </summary>
  222. /// <param name="show"> True to show, false to hide.</param>
  223. internal void SetAPKDisplayedOnLauncher(bool show)
  224. {
  225. var activity = GetActivityWithLaunchIntent();
  226. if (activity == null)
  227. {
  228. activity = GetActivityWithInfoIntent();
  229. }
  230. var intentfilter = SelectSingleNode("/manifest/application/activity/intent-filter[action/@android:name='android.intent.action.MAIN']", nameSpaceManager);
  231. var categoryInfo = SelectSingleNode("/manifest/application/activity/intent-filter/category[@android:name='android.intent.category.INFO']", nameSpaceManager);
  232. var categoryLauncher = SelectSingleNode("/manifest/application/activity/intent-filter/category[@android:name='android.intent.category.LAUNCHER']", nameSpaceManager);
  233. if (show)
  234. {
  235. // Add launcher category
  236. XmlElement newcategory = CreateElement("category");
  237. XmlAttribute newAttribute = CreateAndroidAttribute("name", "android.intent.category.LAUNCHER");
  238. newcategory.Attributes.Append(newAttribute);
  239. if (categoryInfo != null)
  240. {
  241. intentfilter.ReplaceChild(newcategory, categoryInfo);
  242. }
  243. else if (categoryLauncher == null)
  244. {
  245. intentfilter.AppendChild(newcategory);
  246. }
  247. }
  248. else
  249. {
  250. // Add info category
  251. XmlElement newcategory = CreateElement("category");
  252. XmlAttribute newAttribute = CreateAndroidAttribute("name", "android.intent.category.INFO");
  253. newcategory.Attributes.Append(newAttribute);
  254. newAttribute = CreateAndroidAttribute("node", "replace", "tools");
  255. newcategory.Attributes.Append(newAttribute);
  256. if (categoryLauncher != null)
  257. {
  258. intentfilter.ReplaceChild(newcategory, categoryLauncher);
  259. }
  260. else if (categoryInfo == null)
  261. {
  262. intentfilter.AppendChild(newcategory);
  263. }
  264. }
  265. }
  266. }
  267. }