WebviewPackage/Packages/com.bywaystudios.webview/Plugins/Editor/UnityWebViewPostprocessBuild.cs
2026-05-20 15:46:35 +08:00

202 lines
7.3 KiB
C#

using System;
using System.IO;
using System.Text;
using System.Xml;
using UnityEditor;
using UnityEditor.Android;
using UnityEditor.Callbacks;
using UnityEngine;
namespace Byway.UnityWebView
{
public class UnityWebViewPostprocessBuild : IPostGenerateGradleAndroidProject
{
public void OnPostGenerateGradleAndroidProject(string basePath)
{
var changed = false;
var androidManifest = new AndroidManifest(GetManifestPath(basePath));
changed = (androidManifest.SetExported(true) || changed);
changed = (androidManifest.SetWindowSoftInputMode("adjustPan") || changed);
changed = (androidManifest.SetHardwareAccelerated(true) || changed);
if (changed)
{
androidManifest.Save();
Debug.Log("unitywebview: adjusted AndroidManifest.xml.");
}
}
public int callbackOrder
{
get
{
return 1;
}
}
private string GetManifestPath(string basePath)
{
var pathBuilder = new StringBuilder(basePath);
pathBuilder.Append(Path.DirectorySeparatorChar).Append("src");
pathBuilder.Append(Path.DirectorySeparatorChar).Append("main");
pathBuilder.Append(Path.DirectorySeparatorChar).Append("AndroidManifest.xml");
return pathBuilder.ToString();
}
[PostProcessBuild(100)]
public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
{
if (buildTarget == BuildTarget.iOS)
{
string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";
var type = Type.GetType("UnityEditor.iOS.Xcode.PBXProject, UnityEditor.iOS.Extensions.Xcode");
if (type == null)
{
Debug.LogError("unitywebview: failed to get PBXProject. please install iOS build support.");
return;
}
var src = File.ReadAllText(projPath);
//dynamic proj = type.GetConstructor(Type.EmptyTypes).Invoke(null);
var proj = type.GetConstructor(Type.EmptyTypes).Invoke(null);
//proj.ReadFromString(src);
{
var method = type.GetMethod("ReadFromString");
method.Invoke(proj, new object[] { src });
}
var target = "";
//target = proj.GetUnityFrameworkTargetGuid();
{
var method = type.GetMethod("GetUnityFrameworkTargetGuid");
target = (string)method.Invoke(proj, null);
}
//proj.AddFrameworkToProject(target, "WebKit.framework", false);
{
var method = type.GetMethod("AddFrameworkToProject");
method.Invoke(proj, new object[] { target, "WebKit.framework", false });
}
var cflags = "";
if (EditorUserBuildSettings.development)
{
cflags += " -DUNITYWEBVIEW_DEVELOPMENT";
}
cflags = cflags.Trim();
if (!string.IsNullOrEmpty(cflags))
{
// proj.AddBuildProperty(target, "OTHER_LDFLAGS", cflags);
var method = type.GetMethod("AddBuildProperty", new Type[] { typeof(string), typeof(string), typeof(string) });
method.Invoke(proj, new object[] { target, "OTHER_CFLAGS", cflags });
}
var dst = "";
//dst = proj.WriteToString();
{
var method = type.GetMethod("WriteToString");
dst = (string)method.Invoke(proj, null);
}
File.WriteAllText(projPath, dst);
}
}
}
internal class AndroidXmlDocument : XmlDocument
{
private string m_Path;
protected XmlNamespaceManager nsMgr;
public readonly string AndroidXmlNamespace = "http://schemas.android.com/apk/res/android";
public AndroidXmlDocument(string path)
{
m_Path = path;
using (var reader = new XmlTextReader(m_Path))
{
reader.Read();
Load(reader);
}
nsMgr = new XmlNamespaceManager(NameTable);
nsMgr.AddNamespace("android", AndroidXmlNamespace);
}
public string Save()
{
return SaveAs(m_Path);
}
public string SaveAs(string path)
{
using (var writer = new XmlTextWriter(path, new UTF8Encoding(false)))
{
writer.Formatting = Formatting.Indented;
Save(writer);
}
return path;
}
}
internal class AndroidManifest : AndroidXmlDocument
{
private readonly XmlElement ManifestElement;
private readonly XmlElement ApplicationElement;
public AndroidManifest(string path) : base(path)
{
ManifestElement = SelectSingleNode("/manifest") as XmlElement;
ApplicationElement = SelectSingleNode("/manifest/application") as XmlElement;
}
internal XmlNode GetActivityWithLaunchIntent()
{
return
SelectSingleNode(
"/manifest/application/activity[intent-filter/action/@android:name='android.intent.action.MAIN' and "
+ "intent-filter/category/@android:name='android.intent.category.LAUNCHER']",
nsMgr);
}
// for api level 33
internal bool SetExported(bool enabled)
{
bool changed = false;
var activity = GetActivityWithLaunchIntent() as XmlElement;
if (activity == null)
{
return false;
}
if (activity.GetAttribute("exported", AndroidXmlNamespace) != ((enabled) ? "true" : "false"))
{
activity.SetAttribute("exported", AndroidXmlNamespace, (enabled) ? "true" : "false");
changed = true;
}
return changed;
}
internal bool SetWindowSoftInputMode(string mode)
{
bool changed = false;
var activity = GetActivityWithLaunchIntent() as XmlElement;
if (activity == null)
{
return false;
}
if (activity.GetAttribute("windowSoftInputMode", AndroidXmlNamespace) != mode)
{
activity.SetAttribute("windowSoftInputMode", AndroidXmlNamespace, mode);
changed = true;
}
return changed;
}
internal bool SetHardwareAccelerated(bool enabled)
{
bool changed = false;
var activity = GetActivityWithLaunchIntent() as XmlElement;
if (activity == null)
{
return false;
}
if (activity.GetAttribute("hardwareAccelerated", AndroidXmlNamespace) != ((enabled) ? "true" : "false"))
{
activity.SetAttribute("hardwareAccelerated", AndroidXmlNamespace, (enabled) ? "true" : "false");
changed = true;
}
return changed;
}
}
}