Skip to content

Commit

Permalink
Allow some mobile options to be modified from defaults (#1857)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattjohnsonpint authored Aug 18, 2022
1 parent 7ff846f commit 76b1344
Show file tree
Hide file tree
Showing 16 changed files with 95 additions and 62 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- Fix logging loop with NLog sentry ([#1824](https://github.com/getsentry/sentry-dotnet/pull/1824))
- Fix logging loop with Serilog sentry ([#1828](https://github.com/getsentry/sentry-dotnet/pull/1828))
- Skip attachment if stream is empty ([#1854](https://github.com/getsentry/sentry-dotnet/pull/1854))
- Allow some mobile options to be modified from defaults ([#1857](https://github.com/getsentry/sentry-dotnet/pull/1857))

## 3.20.1

Expand Down
2 changes: 1 addition & 1 deletion samples/Sentry.Samples.Android/MainActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class MainActivity : Activity
{
protected override void OnCreate(Bundle? savedInstanceState)
{
SentrySdk.Init(this, o =>
SentrySdk.Init(o =>
{
o.Dsn = "https://eb18e953812b41c3aeb042e666fd3b5c@o447951.ingest.sentry.io/5428537";
o.SendDefaultPii = true; // adds the user's IP address automatically
Expand Down
4 changes: 2 additions & 2 deletions samples/Sentry.Samples.Maui/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ protected override void OnAppearing()
JavaCrashBtn.IsVisible = false;
#endif

#if !(ANDROID || IOS || MACCATALYST)
#if !__MOBILE__
NativeCrashBtn.IsVisible = false;
#endif
base.OnAppearing();
Expand Down Expand Up @@ -73,7 +73,7 @@ private void OnJavaCrashClicked(object sender, EventArgs e)

private void OnNativeCrashClicked(object sender, EventArgs e)
{
#if ANDROID || IOS || MACCATALYST
#if __MOBILE__
SentrySdk.CauseCrash(CrashType.Native);
#endif
}
Expand Down
7 changes: 1 addition & 6 deletions src/Sentry.Maui/Internal/SentryMauiInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@ public void Initialize(IServiceProvider services)
{
var options = services.GetRequiredService<IOptions<SentryMauiOptions>>().Value;
var disposer = services.GetRequiredService<Disposer>();

#if ANDROID
var context = global::Android.App.Application.Context;
var disposable = SentrySdk.Init(context, options);
#else

var disposable = SentrySdk.Init(options);
#endif

// Register the return value from initializing the SDK with the disposer.
// This will ensure that it gets disposed when the service provider is disposed.
Expand Down
3 changes: 3 additions & 0 deletions src/Sentry.Maui/Internal/SentryMauiOptionsSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public override void Configure(SentryMauiOptions options)
{
base.Configure(options);

// NOTE: Anything set here will overwrite options set by the user.
// For option defaults that can be changed, use the constructor in SentryMauiOptions instead.

// We'll initialize the SDK in SentryMauiInitializer
options.InitializeSdk = false;

Expand Down
14 changes: 14 additions & 0 deletions src/Sentry.Maui/SentryMauiOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ namespace Sentry.Maui;
/// </summary>
public class SentryMauiOptions : SentryLoggingOptions
{
/// <summary>
/// Creates a new instance of <see cref="SentryMauiOptions"/>.
/// </summary>
public SentryMauiOptions()
{
// Set defaults for options that are different for MAUI.
// The user can change these. If you want to force a value, use SentryMauiOptionsSetup instead.
// Also, some of these are already set in the base Sentry SDK, but since we don't yet have native targets
// there for all MAUI targets, we'll set them again here.

AutoSessionTracking = true;
DetectStartupTime = StartupTimeDetectionMode.Fast;
}

/// <summary>
/// Gets or sets whether elements that implement <see cref="IText"/>
/// (such as <see cref="Button"/>, <see cref="Label"/>, <see cref="Entry"/>, and others)
Expand Down
2 changes: 1 addition & 1 deletion src/Sentry/CrashType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public enum CrashType
JavaBackgroundThread,
#endif

#if ANDROID || IOS || MACCATALYST
#if __MOBILE__
/// <summary>
/// A native operation that will crash the appliction will be performed by a C library.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Sentry/Internal/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ internal static class Constants
// See: https://github.com/getsentry/sentry-release-registry
#if ANDROID
public const string SdkName = "sentry.dotnet.android";
#elif IOS || MACCATALYST
#elif __IOS__
public const string SdkName = "sentry.dotnet.cocoa";
#else
public const string SdkName = "sentry.dotnet";
Expand Down
4 changes: 2 additions & 2 deletions src/Sentry/Internal/ProcessInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ internal ProcessInfo(
// https://issuetracker.unity3d.com/issues/il2cpp-player-crashes-when-calling-process-dot-getcurrentprocess-dot-starttime
if (options.DetectStartupTime == StartupTimeDetectionMode.Best)
{
#if ANDROID || IOS || MACCATALYST
#if __MOBILE__
options.LogWarning("StartupTimeDetectionMode.Best is not available on this platform. Using 'Fast' mode.");
#else
// StartupTime is set to UtcNow in this constructor.
Expand All @@ -98,7 +98,7 @@ internal ProcessInfo(
}
}

#if !(ANDROID || IOS || MACCATALYST)
#if !__MOBILE__
private static DateTimeOffset GetStartupTime()
{
using var proc = Process.GetCurrentProcess();
Expand Down
1 change: 1 addition & 0 deletions src/Sentry/Internal/SentryScopeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public SentryScopeManager(
ISentryClient rootClient)
{
ScopeStackContainer = scopeStackContainer;

_options = options;
NewStack = () => new[] { new KeyValuePair<Scope, ISentryClient>(new Scope(options), rootClient) };
}
Expand Down
13 changes: 13 additions & 0 deletions src/Sentry/PlatformAbstractions/DeviceInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Sentry.PlatformAbstractions
{
internal static class DeviceInfo
{
#if ANDROID
public const string PlatformName = "Android";
#elif IOS
public const string PlatformName = "iOS";
#elif MACCATALYST
public const string PlatformName = "Mac Catalyst";
#endif
}
}
46 changes: 15 additions & 31 deletions src/Sentry/Platforms/Android/SentrySdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@
using Sentry.Android;
using Sentry.Android.Callbacks;
using Sentry.Android.Extensions;
using Sentry.Extensibility;
using Sentry.Protocol;

// ReSharper disable once CheckNamespace
namespace Sentry;

public static partial class SentrySdk
{
private static AndroidContext? AndroidContext;
private static AndroidContext AppContext { get; set; } = Application.Context;

/// <summary>
/// Initializes the SDK for Android, with an optional configuration options callback.
/// </summary>
/// <param name="context">The Android application context.</param>
/// <param name="configureOptions">The configuration options callback.</param>
/// <returns>An object that should be disposed when the application terminates.</returns>
[Obsolete("It is no longer required to provide the application context when calling Init. " +
"This method may be removed in a future major release.")]
public static IDisposable Init(AndroidContext context, Action<SentryOptions>? configureOptions)
{
var options = new SentryOptions();
configureOptions?.Invoke(options);
return Init(context, options);
AppContext = context;
return Init(configureOptions);
}

/// <summary>
Expand All @@ -32,40 +32,26 @@ public static IDisposable Init(AndroidContext context, Action<SentryOptions>? co
/// <param name="context">The Android application context.</param>
/// <param name="options">The configuration options instance.</param>
/// <returns>An object that should be disposed when the application terminates.</returns>
[Obsolete("It is no longer required to provide the application context when calling Init. " +
"This method may be removed in a future major release.")]
public static IDisposable Init(AndroidContext context, SentryOptions options)
{
AndroidContext = context;
AppContext = context;
return Init(options);
}

private static void InitSentryAndroidSdk(SentryOptions options)
{
// Set options for the managed SDK that don't depend on the Android SDK
options.AutoSessionTracking = true;
options.IsGlobalModeEnabled = true;

// Set default release and distribution
options.Release ??= GetDefaultReleaseString();
options.Distribution ??= GetDefaultDistributionString();

// "Best" mode throws permission exception on Android
options.DetectStartupTime = StartupTimeDetectionMode.Fast;

// Make sure we capture managed exceptions from the Android environment
AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;

// Now initialize the Android SDK if we have been given an AndroidContext
var context = AndroidContext;
if (context == null)
{
options.LogWarning("Running on Android, but did not initialize Sentry with an AndroidContext. " +
"The embedded Sentry Android SDK is disabled. " +
"Call SentrySdk.Init(AndroidContext, SentryOptions) instead.");
return;
}

// Now initialize the Android SDK
SentryAndroidOptions? androidOptions = null;
SentryAndroid.Init(context, new JavaLogger(options),
SentryAndroid.Init(AppContext, new JavaLogger(options),
new OptionsConfigurationCallback(o =>
{
// Capture the android options reference on the outer scope
Expand Down Expand Up @@ -179,7 +165,7 @@ private static void InitSentryAndroidSdk(SentryOptions options)
o.AddIgnoredExceptionForType(JavaClass.ForName("android.runtime.JavaProxyThrowable"));
}));

// Set options for the managed SDK that depend on the Android SDK
// Set options for the managed SDK that depend on the Android SDK. (The user will not be able to modify these.)
options.AddEventProcessor(new AndroidEventProcessor(androidOptions!));
options.CrashedLastRun = () => Java.Sentry.IsCrashedLastRun()?.BooleanValue() is true;
options.EnableScopeSync = true;
Expand All @@ -201,29 +187,27 @@ private static void AndroidEnvironment_UnhandledExceptionRaiser(object? _, Raise

private static string? GetDefaultReleaseString()
{
var context = AndroidContext ?? Application.Context;
var packageName = context.PackageName;
var packageName = AppContext.PackageName;
if (packageName == null)
{
return null;
}

var packageInfo = context.PackageManager?.GetPackageInfo(packageName, PackageInfoFlags.Permissions);
var packageInfo = AppContext.PackageManager?.GetPackageInfo(packageName, PackageInfoFlags.Permissions);
return packageInfo == null ? null : $"{packageName}@{packageInfo.VersionName}+{packageInfo.GetVersionCode()}";
}

private static string? GetDefaultDistributionString() => GetAndroidPackageVersionCode()?.ToString();

private static long? GetAndroidPackageVersionCode()
{
var context = AndroidContext ?? Application.Context;
var packageName = context.PackageName;
var packageName = AppContext.PackageName;
if (packageName == null)
{
return null;
}

var packageInfo = context.PackageManager?.GetPackageInfo(packageName, PackageInfoFlags.Permissions);
var packageInfo = AppContext.PackageManager?.GetPackageInfo(packageName, PackageInfoFlags.Permissions);
return packageInfo?.GetVersionCode();
}

Expand Down
9 changes: 1 addition & 8 deletions src/Sentry/Platforms/iOS/SentrySdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,10 @@ private static void InitSentryCocoaSdk(SentryOptions options)
args.ExceptionMode = ObjCRuntime.MarshalManagedExceptionMode.UnwindNativeCode;
};

// Set options for the managed SDK that don't depend on the Cocoa SDK
options.AutoSessionTracking = true;
options.IsGlobalModeEnabled = true;

// Set default release and distribution
options.Release ??= GetDefaultReleaseString();
options.Distribution ??= GetDefaultDistributionString();

// "Best" mode throws platform not supported exception. Use "Fast" mode instead.
options.DetectStartupTime = StartupTimeDetectionMode.Fast;

// Set options for the Cocoa SDK
var cocoaOptions = new SentryCocoaOptions();

Expand Down Expand Up @@ -170,7 +163,7 @@ private static void InitSentryCocoaSdk(SentryOptions options)
// Now initialize the Cocoa SDK
SentryCocoaSdk.StartWithOptionsObject(cocoaOptions);

// Set options for the managed SDK that depend on the Cocoa SDK
// Set options for the managed SDK that depend on the Cocoa SDK. (The user will not be able to modify these.)
options.AddEventProcessor(new IosEventProcessor(cocoaOptions!));
options.CrashedLastRun = () => SentryCocoaSdk.CrashedLastRun;
options.EnableScopeSync = true;
Expand Down
2 changes: 1 addition & 1 deletion src/Sentry/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@


// The targets for these platforms are not CLS Compliant
#if !(ANDROID || IOS || MACCATALYST)
#if !__MOBILE__
[assembly: CLSCompliant(true)]
#endif
43 changes: 36 additions & 7 deletions src/Sentry/SentryOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
using Sentry.Internal;
using Sentry.Internal.Http;
using Sentry.Internal.ScopeStack;
using Sentry.PlatformAbstractions;
using static Sentry.Constants;
using Runtime = Sentry.PlatformAbstractions.Runtime;

#if HAS_DIAGNOSTIC_INTEGRATION
using Sentry.Internals.DiagnosticSource;
#endif
Expand All @@ -26,6 +27,26 @@ public partial class SentryOptions
{
private Dictionary<string, string>? _defaultTags;

#if __MOBILE__

internal IScopeStackContainer? ScopeStackContainer { get; } = new GlobalScopeStackContainer();

/// <summary>
/// Specifies whether to use global scope management mode.
/// Always <c>true</c> for mobile targets.
/// </summary>
public bool IsGlobalModeEnabled
{
get => true;
set
{
if (value is false)
{
_diagnosticLogger?.LogWarning("Cannot disable Global Mode on {0}", DeviceInfo.PlatformName);
}
}
}
#else
internal IScopeStackContainer? ScopeStackContainer { get; set; }

/// <summary>
Expand All @@ -36,6 +57,7 @@ public bool IsGlobalModeEnabled
get => ScopeStackContainer is GlobalScopeStackContainer;
set => ScopeStackContainer = value ? new GlobalScopeStackContainer() : new AsyncLocalScopeStackContainer();
}
#endif

/// <summary>
/// A scope set outside of Sentry SDK. If set, the global parameters from the SDK's scope will be sent to the observed scope.<br/>
Expand Down Expand Up @@ -573,13 +595,19 @@ public StackTraceMode StackTraceMode
public long MaxAttachmentSize { get; set; } = 20 * 1024 * 1024;

/// <summary>
/// Whether the SDK should attempt to detect the app's and device's startup time.
/// The mode that the SDK should use when attempting to detect the app's and device's startup time.
/// </summary>
/// <remarks>
/// Note that the highest precision value relies on <see cref="System.Diagnostics.Process.GetCurrentProcess"/>
/// which might not be available. For example on Unity's IL2CPP.
/// Additionally, "Best" mode is not available on mobile platforms.
/// </remarks>
public StartupTimeDetectionMode DetectStartupTime { get; set; } = StartupTimeDetectionMode.Best;
public StartupTimeDetectionMode DetectStartupTime { get; set; } =
#if __MOBILE__
StartupTimeDetectionMode.Fast;
#else
StartupTimeDetectionMode.Best;
#endif

/// <summary>
/// Determines the duration of time a session can stay paused before it's considered ended.
Expand All @@ -589,10 +617,11 @@ public StackTraceMode StackTraceMode
/// </remarks>
public TimeSpan AutoSessionTrackingInterval { get; set; } = TimeSpan.FromSeconds(30);

#if ANDROID || IOS || MACCATALYST
#if __MOBILE__
/// <summary>
/// Whether the SDK should start a session automatically when it's initialized and
/// end the session when it's closed.
/// On mobile application platforms, this is enabled by default.
/// </summary>
public bool AutoSessionTracking { get; set; } = true;
#else
Expand All @@ -601,8 +630,8 @@ public StackTraceMode StackTraceMode
/// end the session when it's closed.
/// </summary>
/// <remarks>
/// Note: this is disabled by default in the current version, but will become
/// enabled by default in the next major version.
/// Note: this is disabled by default in the current version (except for mobile targets and MAUI),
/// but will become enabled by default in the next major version.
/// Currently this only works for release health in client mode
/// (desktop, mobile applications, but not web servers).
/// </remarks>
Expand Down Expand Up @@ -691,7 +720,7 @@ public SentryOptions()

#if ANDROID
Android = new AndroidOptions(this);
#elif IOS || MACCATALYST
#elif __IOS__
iOS = new IosOptions(this);
#endif

Expand Down
Loading

0 comments on commit 76b1344

Please sign in to comment.