631 lines
18 KiB
C#
631 lines
18 KiB
C#
// ----------------------------------------
|
|
//
|
|
// BuglyCommon.cs
|
|
//
|
|
// Author:
|
|
// bugly, <bugly@tencent.com>
|
|
//
|
|
// Copyright (c) 2023 Bugly, Tencent. All rights reserved.
|
|
//
|
|
// ----------------------------------------
|
|
//
|
|
using UnityEngine;
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
using System.Runtime.InteropServices;
|
|
using AOT;
|
|
|
|
public class BuglyCommon
|
|
{
|
|
private static int _crashReporterType = 1; // Default=0,1=Bugly-V2,MSDKBugly=2, IMSDKBugly=3
|
|
private static bool _debugMode = false;
|
|
private static Func<Dictionary<string, string>> _LogCallbackExtrasHandler;
|
|
|
|
#if UNITY_ANDROID
|
|
// Log Level
|
|
private static int _crashReproterLogLevel = 0; // OFF=0, ERROR=1, WARN=2, INFO=3, DEBUG=4, VERBOS=5
|
|
public static int BuglyCrashReporterLogLevel
|
|
{
|
|
get { return _crashReproterLogLevel; }
|
|
set { _crashReproterLogLevel = value; }
|
|
}
|
|
|
|
// The Bugly Performance Plugin List, Empty means Open Crash Only
|
|
private static string[] _pluginArray = {};
|
|
|
|
#elif UNITY_IPHONE || UNITY_IOS
|
|
private static int _crashReproterCustomizedLogLevel = 2; // Off=0,Error=1,Warn=2,Info=3,Debug=4
|
|
public static int BuglyReproterCustomizedLogLevel
|
|
{
|
|
get { return _crashReproterCustomizedLogLevel;}
|
|
set { _crashReproterCustomizedLogLevel = value;}
|
|
}
|
|
|
|
// The Bugly Plugin List, default mode is Open Crash Only
|
|
private static string[] _pluginArray = {"BuglyCrashMonitorPlugin", "RMMemoryMonitorPlugin"};
|
|
|
|
#endif
|
|
|
|
public static string[] BuglyPluginArray
|
|
{
|
|
get { return _pluginArray;}
|
|
set { _pluginArray = value;}
|
|
}
|
|
|
|
|
|
public static void InitBuglyAgent(string appId, string appKey)
|
|
{
|
|
InitBuglySDK(appId, appKey);
|
|
}
|
|
|
|
public static void SetBuglyUserId(string userId)
|
|
{
|
|
SetUserId(userId);
|
|
}
|
|
|
|
public static void SetBuglyDeviceId(string deviceId)
|
|
{
|
|
SetDeviceId(deviceId);
|
|
}
|
|
|
|
public static void SetBuglyAdditionalAttachmentPaths(string[] pathArray)
|
|
{
|
|
SetAdditionalAttachmentPaths(pathArray);
|
|
}
|
|
|
|
public static void SetBuglyCrashHandlerListener(BuglyCallback.ListenerAdapter listener)
|
|
{
|
|
SetCrashHandlerListener(listener);
|
|
}
|
|
|
|
public static void AddBuglyKeyAndValueInScene(string key, string value)
|
|
{
|
|
AddKeyAndValueInScene(key, value);
|
|
}
|
|
|
|
public static void ConfigBuglyDefaultBeforeInit (string channel, string version, string buildNum, string user, string model)
|
|
{
|
|
ConfigDefaultBeforeInit (channel, version, buildNum, user, model);
|
|
}
|
|
|
|
public static void LogBuglyRecord(LogSeverity level, string format, params object[] args)
|
|
{
|
|
LogRecord (level, string.Format (format, args));
|
|
}
|
|
|
|
public static void SetSDKUnityVersion(){
|
|
SetUnityVersion();
|
|
}
|
|
|
|
public static void ReportBuglyException (int type, string name, string reason, string stackTrace, bool quitProgram)
|
|
{
|
|
ReportException(type, name, reason, stackTrace, quitProgram);
|
|
}
|
|
|
|
public static void SetBuglyReporterType(int type){
|
|
_crashReporterType = type;
|
|
}
|
|
|
|
public static bool BuglyDebugMode
|
|
{
|
|
get { return _debugMode;}
|
|
set { _debugMode = value;}
|
|
}
|
|
|
|
public static Func<Dictionary<string, string>> BuglyLogCallbackExtrasHandler
|
|
{
|
|
get { return _LogCallbackExtrasHandler;}
|
|
set { _LogCallbackExtrasHandler = value;}
|
|
}
|
|
|
|
public static void BuglySetLogLevel(int logLevel)
|
|
{
|
|
SetLogLevel(logLevel);
|
|
}
|
|
|
|
public static void BuglyStartInspectLeakObj(AndroidJavaObject javaObject)
|
|
{
|
|
StartInspectLeakObj(javaObject);
|
|
}
|
|
|
|
public static void BuglyLaunchAddTag(string tag)
|
|
{
|
|
LaunchAddTag(tag);
|
|
}
|
|
|
|
public static void BuglyLaunchSpanStart(string spanName, string parentSpanName)
|
|
{
|
|
LaunchSpanStart(spanName, parentSpanName);
|
|
}
|
|
|
|
public static void BuglyLaunchSpanEnd(string spanName)
|
|
{
|
|
LaunchSpanEnd(spanName);
|
|
}
|
|
|
|
public static void BuglyReportAppFullLaunch()
|
|
{
|
|
// launch end
|
|
ReportAppFullLaunch();
|
|
}
|
|
|
|
#if UNITY_ANDROID
|
|
|
|
#region Interface for Android
|
|
|
|
private static bool _isInit = false;
|
|
|
|
// fetch java class
|
|
private const string GAME_AGENT_CLASS = "com.tencent.bugly.agent.GameAgentPro";
|
|
private const int TYPE_U_3D_CRASH = 4;
|
|
private const int GAME_TYPE_UNITY = 2;
|
|
private static bool _hasSetGameType = false;
|
|
private static AndroidJavaClass _gameAgentClass = null;
|
|
|
|
// init set
|
|
private static string _appVersion = "";
|
|
private static string _buildNum = "";
|
|
private static string _uniqueId = "";
|
|
private static string _userId = "";
|
|
private static string _deviceModel = "";
|
|
private static string _appVersionType = "Unknown";
|
|
private static string _appChannel = "";
|
|
private static int _logLevel = 0;
|
|
|
|
private static AndroidJavaClass gameAgent
|
|
{
|
|
get {
|
|
_gameAgentClass ??= new AndroidJavaClass(GAME_AGENT_CLASS);
|
|
if (_hasSetGameType) return _gameAgentClass;
|
|
|
|
_gameAgentClass.CallStatic ("setGameType", GAME_TYPE_UNITY);
|
|
_hasSetGameType = true;
|
|
return _gameAgentClass;
|
|
}
|
|
}
|
|
|
|
// init
|
|
private static void InitBuglySDK(string appId, string appKey)
|
|
{
|
|
try {
|
|
if (_isInit)
|
|
{
|
|
UnityEngine.Debug.Log("Bugly has init, return.");
|
|
return;
|
|
}
|
|
|
|
gameAgent.CallStatic("initAgent", appId, appKey,
|
|
_appVersion, _buildNum, _uniqueId, _userId, _deviceModel, _appVersionType, _appChannel, BuglyDebugMode,
|
|
_logLevel, BuglyPluginArray);
|
|
_isInit = true;
|
|
|
|
UnityEngine.Debug.Log("Bugly init success");
|
|
} catch(Exception ex){
|
|
UnityEngine.Debug.Log("Bugly init failed");
|
|
UnityEngine.Debug.Log(ex.ToString());
|
|
}
|
|
}
|
|
|
|
private static void SetUserId(string userId)
|
|
{
|
|
try
|
|
{
|
|
_userId = userId;
|
|
|
|
if (_isInit)
|
|
{
|
|
gameAgent.CallStatic("updateUserIdAgent", userId);
|
|
}
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void SetDeviceId(string deviceId)
|
|
{
|
|
try
|
|
{
|
|
_uniqueId = deviceId;
|
|
|
|
if (_isInit)
|
|
{
|
|
gameAgent.CallStatic("updateUniqueIdAgent", deviceId);
|
|
}
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void SetAdditionalAttachmentPaths(string[] pathArray){
|
|
try {
|
|
gameAgent.CallStatic("setAdditionalAttachmentPathsAgent", pathArray);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void SetCrashHandlerListener(BuglyCallback.ListenerAdapter listener)
|
|
{
|
|
try {
|
|
gameAgent.CallStatic("setCrashHandlerListenerAgent", listener);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void AddKeyAndValueInScene(string key, string value){
|
|
try {
|
|
gameAgent.CallStatic("putUserDataAgent", key, value);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void ConfigDefaultBeforeInit(string channel, string version, string buildNum, string user, string model)
|
|
{
|
|
_appChannel = channel;
|
|
_appVersion = version;
|
|
_buildNum = buildNum;
|
|
_userId = user;
|
|
_deviceModel = model;
|
|
}
|
|
|
|
private static void LogRecord(LogSeverity level, string message)
|
|
{
|
|
// no impl
|
|
}
|
|
|
|
private static void SetUnityVersion()
|
|
{
|
|
// for special scene, no impl
|
|
}
|
|
|
|
private static void ReportException(int type, string errorName, string errorMsg, string stackTrace, bool quitProgram)
|
|
{
|
|
try {
|
|
gameAgent.CallStatic("postExceptionAgent",
|
|
TYPE_U_3D_CRASH, errorName, errorMsg, stackTrace, quitProgram);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void SetLogLevel(int logLevel)
|
|
{
|
|
try {
|
|
gameAgent.CallStatic("updateLogLevelAgent", logLevel);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
// java memory leak
|
|
private static void StartInspectLeakObj(AndroidJavaObject javaObject)
|
|
{
|
|
try {
|
|
gameAgent.CallStatic("startInspectLeakObjAgent", javaObject);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
// launch
|
|
private static void LaunchAddTag(string tag)
|
|
{
|
|
try {
|
|
gameAgent.CallStatic("launchAddTagAgent", tag);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void LaunchSpanStart(string spanName, string parentSpanName)
|
|
{
|
|
try {
|
|
gameAgent.CallStatic("launchSpanStartAgent", spanName, parentSpanName);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void LaunchSpanEnd(string spanName)
|
|
{
|
|
try {
|
|
gameAgent.CallStatic("launchSpanEndAgent", spanName);
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void ReportAppFullLaunch()
|
|
{
|
|
try {
|
|
gameAgent.CallStatic("reportAppFullLaunchAgent");
|
|
} catch (Exception ex) {
|
|
Console.WriteLine("Exception: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#elif UNITY_IPHONE || UNITY_IOS
|
|
|
|
#region Interface for iOS
|
|
|
|
private static bool _crashReporterTypeConfiged = false;
|
|
private delegate string OnBuglyCrashCallback(string name, string reason, string user_info);
|
|
private static BuglyCallback.ListenerAdapter _listener = null;
|
|
|
|
[DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern void _BuglySetUnityCallback(OnBuglyCrashCallback callbackHandler);
|
|
|
|
|
|
private static void ConfigCrashReporterType(){
|
|
if (!_crashReporterTypeConfiged) {
|
|
try {
|
|
_BuglyConfigCrashReporterType(_crashReporterType);
|
|
_crashReporterTypeConfiged = true;
|
|
} catch {
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void ConfigDefaultBeforeInit(string channel, string version, string buildNum, string user, string model){
|
|
ConfigCrashReporterType();
|
|
|
|
try {
|
|
_BuglyDefaultConfig(channel, version, user, null);
|
|
} catch {
|
|
|
|
}
|
|
}
|
|
|
|
private static void EnableDebugMode(bool enable){
|
|
_debugMode = enable;
|
|
}
|
|
|
|
private static void InitBuglySDK (string appId, string appKey)
|
|
{
|
|
ConfigCrashReporterType();
|
|
|
|
if(!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appKey)) {
|
|
int count = _pluginArray.Length;
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(count * IntPtr.Size);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
IntPtr strPtr = Marshal.StringToHGlobalAnsi(_pluginArray[i]);
|
|
Marshal.WriteIntPtr(ptr, i * IntPtr.Size, strPtr);
|
|
}
|
|
|
|
_BuglySetPluginArray(ptr, count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
IntPtr strPtr = Marshal.ReadIntPtr(ptr, i * IntPtr.Size);
|
|
Marshal.FreeHGlobal(strPtr);
|
|
}
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
_BuglyInit(appId, appKey, _debugMode, _crashReproterCustomizedLogLevel); // Log level
|
|
}
|
|
}
|
|
|
|
private static void SetUnityVersion(){
|
|
ConfigCrashReporterType();
|
|
|
|
_BuglySetExtraConfig("UnityVersion", Application.unityVersion);
|
|
}
|
|
|
|
private static void SetUserId(string userid){
|
|
if(!string.IsNullOrEmpty(userid)) {
|
|
ConfigCrashReporterType();
|
|
|
|
_BuglySetUserId(userid);
|
|
}
|
|
}
|
|
|
|
private static void SetDeviceId(string deviceInfo){
|
|
if(!string.IsNullOrEmpty(deviceInfo)) {
|
|
ConfigCrashReporterType();
|
|
|
|
_BuglySetDeviceId(deviceInfo);
|
|
}
|
|
}
|
|
|
|
private static void SetDumpFilePath(string path){
|
|
|
|
}
|
|
|
|
private static void ReportException (int type, string name, string reason, string stackTrace, bool quitProgram)
|
|
{
|
|
ConfigCrashReporterType();
|
|
|
|
string extraInfo = "";
|
|
Dictionary<string, string> extras = null;
|
|
if (_LogCallbackExtrasHandler != null) {
|
|
extras = _LogCallbackExtrasHandler();
|
|
}
|
|
if (extras == null || extras.Count == 0) {
|
|
extras = new Dictionary<string, string> ();
|
|
extras.Add ("UnityVersion", Application.unityVersion);
|
|
}
|
|
|
|
if (extras != null && extras.Count > 0) {
|
|
if (!extras.ContainsKey("UnityVersion")) {
|
|
extras.Add ("UnityVersion", Application.unityVersion);
|
|
}
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
foreach(KeyValuePair<string,string> kvp in extras){
|
|
builder.Append(string.Format("\"{0}\" : \"{1}\"", kvp.Key, kvp.Value)).Append(" , ");
|
|
}
|
|
extraInfo = string.Format("{{ {0} }}", builder.ToString().TrimEnd(" , ".ToCharArray()));
|
|
}
|
|
|
|
// 4 is C# exception
|
|
_BuglyReportException(4, name, reason, stackTrace, extraInfo, quitProgram);
|
|
}
|
|
|
|
private static void AddKeyAndValueInScene(string key, string value){
|
|
ConfigCrashReporterType();
|
|
|
|
_BuglySetKeyValue(key, value);
|
|
}
|
|
|
|
private static void AddExtraDataWithException(string key, string value) {
|
|
|
|
}
|
|
|
|
private static void LogRecord(LogSeverity level, string message){
|
|
|
|
ConfigCrashReporterType();
|
|
|
|
_BuglyLogMessage(LogSeverityToInt(level), null, message);
|
|
}
|
|
|
|
private static int LogSeverityToInt(LogSeverity logLevel){
|
|
int level = 5;
|
|
switch(logLevel) {
|
|
case LogSeverity.Log:
|
|
level = 5;
|
|
break;
|
|
case LogSeverity.LogDebug:
|
|
level = 4;
|
|
break;
|
|
case LogSeverity.LogInfo:
|
|
level = 3;
|
|
break;
|
|
case LogSeverity.LogWarning:
|
|
case LogSeverity.LogAssert:
|
|
level = 2;
|
|
break;
|
|
case LogSeverity.LogError:
|
|
case LogSeverity.LogException:
|
|
level = 1;
|
|
break;
|
|
default:
|
|
level = 0;
|
|
break;
|
|
}
|
|
return level;
|
|
}
|
|
|
|
private static void SetLogLevel(int logLevel)
|
|
{
|
|
|
|
}
|
|
|
|
private static void StartInspectLeakObj(AndroidJavaObject javaObject)
|
|
{
|
|
// no impl for iOS
|
|
}
|
|
|
|
// launch
|
|
private static void LaunchAddTag(string tag)
|
|
{
|
|
|
|
}
|
|
|
|
private static void LaunchSpanStart(string spanName, string parentSpanName)
|
|
{
|
|
|
|
}
|
|
|
|
private static void LaunchSpanEnd(string spanName)
|
|
{
|
|
|
|
}
|
|
|
|
private static void ReportAppFullLaunch()
|
|
{
|
|
|
|
}
|
|
|
|
[MonoPInvokeCallback(typeof(OnBuglyCrashCallback))]
|
|
public static string OnBuglyCrashCallbackFunc(string name, string reason, string user_info)
|
|
{
|
|
if(_listener != null){
|
|
return _listener.OnBuglyCrashCallback(name, reason, user_info);
|
|
}
|
|
|
|
return "empty string";
|
|
}
|
|
private static void SetCrashHandlerListener(BuglyCallback.ListenerAdapter listener)
|
|
{
|
|
if(listener != null){
|
|
_listener = listener;
|
|
_BuglySetUnityCallback(OnBuglyCrashCallbackFunc);
|
|
}
|
|
}
|
|
|
|
private static void SetAdditionalAttachmentPaths(string[] pathArray){
|
|
if (pathArray != null && pathArray.Length > 0){
|
|
int count = pathArray.Length;
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(count * IntPtr.Size);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
IntPtr strPtr = Marshal.StringToHGlobalAnsi(pathArray[i]);
|
|
Marshal.WriteIntPtr(ptr, i * IntPtr.Size, strPtr);
|
|
}
|
|
|
|
_BuglySetAdditionalAttachmentPaths(ptr, count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
IntPtr strPtr = Marshal.ReadIntPtr(ptr, i * IntPtr.Size);
|
|
Marshal.FreeHGlobal(strPtr);
|
|
}
|
|
Marshal.FreeHGlobal(ptr);
|
|
}
|
|
}
|
|
|
|
// --- dllimport start ---
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglyInit(string appId, string appKey, bool debug, int level);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglySetUserId(string userId);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglySetDeviceId(string deviceId);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglySetKeyValue(string key, string value);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglyReportException(int type, string name, string reason, string stackTrace, string extras, bool quit);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglyDefaultConfig(string channel, string version, string user, string deviceId);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglyLogMessage(int level, string tag, string log);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglyConfigCrashReporterType(int type);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglySetExtraConfig(string key, string value);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglySetAdditionalAttachmentPaths(IntPtr pathArray, int count);
|
|
|
|
[DllImport("__Internal")]
|
|
private static extern void _BuglySetPluginArray(IntPtr pluginArray, int count);
|
|
|
|
// dllimport end
|
|
#endregion
|
|
|
|
#endif
|
|
}
|