/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * Licensed under the Oculus SDK License Agreement (the "License"); * you may not use the Oculus SDK except in compliance with the License, * which is provided at the time of installation or download, or which * otherwise accompanies this software in either electronic or hard copy form. * * You may obtain a copy of the License at * * https://developer.oculus.com/licenses/oculussdk/ * * Unless required by applicable law or agreed to in writing, the Oculus SDK * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; internal class OVRConfigurationTaskSourceCode { private static Func OpenAssetDelegate = AssetDatabase.OpenAsset; public static void Mock() { OpenAssetDelegate = null; } public static void Unmock() { OpenAssetDelegate = AssetDatabase.OpenAsset; } private static IEnumerable _expectedMethods; private static IEnumerable ExpectedMethods { get { if (_expectedMethods == null) { _expectedMethods = typeof(OVRProjectSetup).GetMethods(BindingFlags.Public | BindingFlags.Static) .Where(method => method.Name == "AddTask"); } return _expectedMethods; } } private OVRConfigurationTask _task; private readonly StackTrace _stackTrace; private Object _object; private bool _processed; public bool Valid { get { if (!_processed) { ProcessStackTrace(); } return _object != null; } } public int Line { get; private set; } public string FilePath { get; private set; } public OVRConfigurationTaskSourceCode(OVRConfigurationTask task) { _task = task; _stackTrace = new StackTrace(true); } public void ProcessStackTrace() { if (FindPathAndLine(out var path, out var line)) { path = path.Replace("\\", "/"); if (path.StartsWith(Application.dataPath)) { FilePath = Path.Combine("Assets/", path.Substring(Application.dataPath.Length + 1)); Line = line; _object = AssetDatabase.LoadAssetAtPath(FilePath, typeof(Object)); } } _processed = true; } public bool Open() { if (Valid) { OpenAssetDelegate?.Invoke(_object, Line); } OVRTelemetry.Start(OVRProjectSetupTelemetryEvent.EventTypes.GoToSource) .AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Uid, _task.Uid.ToString()) .AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.BuildTargetGroup, BuildTargetGroup.Unknown.ToString()) .AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Value, Valid ? "true" : "false") .Send(); return Valid; } private StackFrame FindStackFrame() { // Depth 2, Just before the constructor StackFrame frame = _stackTrace.GetFrame(2); var method = frame.GetMethod(); if (ExpectedMethods.Contains(method)) { // Depth 3, Just before OVRProjectSetup AddTask frame = _stackTrace.GetFrame(3); } return frame; } private bool FindPathAndLine(out string path, out int line) { var frame = FindStackFrame(); if (frame == null) { path = null; line = -1; return false; } path = frame.GetFileName(); line = frame.GetFileLineNumber(); return true; } }