/**************************************************************************** * Copyright 2019 Nreal Techonology Limited.All rights reserved. * * This file is part of NRSDK. * * https://www.nreal.ai/ * *****************************************************************************/ namespace NRKernal { using System; using System.Text; using System.Xml; using System.IO; using System.Linq.Expressions; using System.Collections.Generic; using UnityEngine; /// A list of the android. internal class AndroidGradleTemplate { private enum EPatcherType { EPT_NONE = 0, EPT_PLUGIN_VERSION = 1, EPT_ADD_DEPENDENCIES = 2, EPT_REMOVE_DEPENDENCIES = 3, EPT_ADD_SUPPORT = 4, } private interface IGradlePatcher { void PreprocessLine(string line); bool ProcessLine(string line, ref string result); } private class GradlePluginVersionPatcher : IGradlePatcher { const string PLUGIN_VERSION_TOKEN = "com.android.tools.build:gradle:"; private int mMajorVersionNum; private int mMiddleVersionNum; private int mMinorVersionNum; public GradlePluginVersionPatcher() { mMajorVersionNum = 0; mMiddleVersionNum = 0; mMinorVersionNum = 0; } public void SetMinPluginVersion(int major, int middle, int minor) { mMajorVersionNum = major; mMiddleVersionNum = middle; mMinorVersionNum = minor; } public void PreprocessLine(string line) { } public bool ProcessLine(string line, ref string result) { bool updateVersion = false; var idx = line.IndexOf(PLUGIN_VERSION_TOKEN); if (idx > 0) { string subLine = line.Substring(idx + PLUGIN_VERSION_TOKEN.Length); string subVersion = subLine.Substring(0, subLine.IndexOf('\'')); Debug.LogFormat("subVersion : {0}", subVersion); string[] versions = subVersion.Split('.'); if (versions.Length == 3) { int.TryParse(versions[0], out int vMain); int.TryParse(versions[1], out int vMiddle); int.TryParse(versions[2], out int vMin); if (vMain < mMajorVersionNum) { updateVersion = true; } else if(vMain == mMajorVersionNum) { if(vMiddle < mMiddleVersionNum) { updateVersion = true; } else if(vMiddle == mMiddleVersionNum) { if(vMin < mMinorVersionNum) { updateVersion = true; } } } if (updateVersion) { result = line.Replace(subVersion, "3.4.3"); Debug.LogFormat("update gradle setting : {0} --> {1}", subVersion, "3.4.3"); } } } return updateVersion; } } private class GradleAddDependenciesPatcher : IGradlePatcher { const string DEPS_MARK = "**DEPS**"; private List mDependencies; public GradleAddDependenciesPatcher() { mDependencies = new List(); } public void AddDependency(string dependency) { mDependencies.Add(dependency); } public void PreprocessLine(string line) { for(int i = mDependencies.Count - 1; i >= 0; i--) { if(line.Contains(mDependencies[i])) { //this dependency is already in the gradle file mDependencies.RemoveAt(i); } } } public bool ProcessLine(string line, ref string result) { if(mDependencies.Count > 0 && line.Contains(DEPS_MARK)) { result = " " + string.Join("\n ", mDependencies); result = result + "\n" + line; return true; } return false; } } private class GradleRemoveDependenciesPatcher : IGradlePatcher { private List mDependencies; public GradleRemoveDependenciesPatcher() { mDependencies = new List(); } public void RemoveDependency(string dependency) { mDependencies.Add(dependency); } public void PreprocessLine(string line) { } public bool ProcessLine(string line, ref string result) { bool includeDeps = false; for (int i = 0; i < mDependencies.Count; i++) { if (line.Contains(mDependencies[i])) { includeDeps = true; //remove this line result = null; break; } } return includeDeps; } } private class GradleAddSupportPatcher : IGradlePatcher { private Dictionary mKeyTokenAlreadyInFile = new Dictionary(); private bool mIsFirst = true; private List mTokenList = new List(); public void PreprocessLine(string line) { for(int i = 0; i < mTokenList.Count; i++) { var token = mTokenList[i]; if (line.Contains(token)) { mKeyTokenAlreadyInFile[token] = true; } } } public bool ProcessLine(string line, ref string result) { string tempLine = ""; if (mIsFirst) { tempLine = GetSupportStringNotInFile(); mIsFirst = false; } foreach (var pair in mKeyTokenAlreadyInFile) { if (pair.Value) { if (line.Contains(pair.Key)) { result = tempLine + pair.Key + "=true"; return true; } } } result = tempLine + line; return false; } private string GetSupportStringNotInFile() { string line = ""; foreach (var pair in mKeyTokenAlreadyInFile) { if (!pair.Value) { line = string.Format("{0}=true\n{1}", pair.Key, line); } } return line; } public void AddSupport(string keyToken) { mKeyTokenAlreadyInFile.Add(keyToken, false); mTokenList.Add(keyToken); } } Dictionary mPatchers = null; string m_Path; public AndroidGradleTemplate(string path) { m_Path = path; mPatchers = new Dictionary(); } private T GetOrAddPatcher(EPatcherType type) where T : IGradlePatcher, new() { if (!mPatchers.TryGetValue(type, out IGradlePatcher patcher)) { patcher = new T(); mPatchers.Add(type, patcher); } return (T)patcher; } public void SetMinPluginVersion(int major, int middle, int minor) { GradlePluginVersionPatcher pluginVersionPatcher = GetOrAddPatcher( EPatcherType.EPT_PLUGIN_VERSION); pluginVersionPatcher.SetMinPluginVersion(major, middle, minor); } public void AddDenpendency(string dependency) { GradleAddDependenciesPatcher addDepPatcher = GetOrAddPatcher( EPatcherType.EPT_ADD_DEPENDENCIES); addDepPatcher.AddDependency(dependency); } public void RemoveDependency(string dependency) { GradleRemoveDependenciesPatcher removeDepPatcher = GetOrAddPatcher( EPatcherType.EPT_REMOVE_DEPENDENCIES); removeDepPatcher.RemoveDependency(dependency); } public void AddSupport(string keyToken) { GradleAddSupportPatcher addSupportPatcher = GetOrAddPatcher( EPatcherType.EPT_ADD_SUPPORT); addSupportPatcher.AddSupport(keyToken); } public void PreprocessGradleFile() { if (mPatchers.Count <= 0) return; try { List content = new List(); var lines = File.ReadAllLines(m_Path); string newLine = null; foreach (string line in lines) { foreach (var pair in mPatchers) { pair.Value.PreprocessLine(line); } } foreach (string line in lines) { newLine = line; foreach (var pair in mPatchers) { if(pair.Value.ProcessLine(line, ref newLine)) { break; } } //Original line may be empty, not null if (newLine != null) { content.Add(newLine); } } File.WriteAllLines(m_Path, content); } catch (Exception ex) { Debug.LogErrorFormat("PreprocessGradleFile exception : {0}", ex.Message); } } } }