Skip to content

fix: Update Android SDK build integration #1318

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Fixes

- Fixed native support build integration for Android ([#1318](https://github.com/getsentry/sentry-unity/pull/1318))
- The SDK filters `System.Net.WebException` and `System.Net.Sockets.SocketException` by default ([#1294](https://github.com/getsentry/sentry-unity/pull/1294))
- The SDK no longer runs performance auto instrumentation with the SDK disabled ([#1314](https://github.com/getsentry/sentry-unity/pull/1314))
- Fixed an issue where the SDK would throw a `NullReferenceException` when trying to capture a log message ([#1309](https://github.com/getsentry/sentry-unity/pull/1309))
Expand Down
17 changes: 6 additions & 11 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -184,20 +184,15 @@ Expected to exist:
<!-- Build the Android SDK: dotnet msbuild /t:BuildAndroidSDK src/Sentry.Unity -->
<Target Name="BuildAndroidSDK" Condition="'$(MSBuildProjectName)' == 'Sentry.Unity'
And !Exists('$(SentryAndroidArtifactsDestination)')" BeforeTargets="BeforeBuild">
<Error Condition="!Exists('$(SentryAndroidRoot)')" Text="Couldn't find the Android root at $(SentryAndroidRoot)."></Error>
<Message Importance="High" Text="Building Sentry Android SDK."></Message>
<Error Condition="!Exists('$(SentryAndroidRoot)')" Text="Couldn't find the Android root at $(SentryAndroidRoot)." />
<Message Importance="High" Text="Building Sentry Android SDK." />

<Exec WorkingDirectory="$(SentryAndroidRoot)" EnvironmentVariables="JAVA_HOME=$(JAVA_HOME_17_X64)" Command="./gradlew -PsentryAndroidSdkName=sentry.native.android.unity :sentry-android-core:assembleRelease :sentry-android-ndk:assembleRelease :sentry:jar --no-daemon --stacktrace --warning-mode none"></Exec>
<Exec WorkingDirectory="$(SentryAndroidRoot)" EnvironmentVariables="JAVA_HOME=$(JAVA_HOME_17_X64)"
Command="./gradlew -PsentryAndroidSdkName=sentry.native.android.unity sentry-android-core:publishAllPublicationsToUnityMavenRepository sentry-android-ndk:publishAllPublicationsToUnityMavenRepository sentry:publishAllPublicationsToUnityMavenRepository sentry-android:publishAllPublicationsToUnityMavenRepository --no-daemon --stacktrace --warning-mode none" />

<ItemGroup>
<AndroidSdkArtifacts Include="$(SentryAndroidRoot)sentry-android-ndk/build/outputs/aar/sentry-android-ndk-release.aar" />
<AndroidSdkArtifacts Include="$(SentryAndroidRoot)sentry-android-core/build/outputs/aar/sentry-android-core-release.aar" />
</ItemGroup>

<Copy SourceFiles="@(AndroidSdkArtifacts)" DestinationFiles="@(AndroidSdkArtifacts->'$(SentryAndroidArtifactsDestination)%(RecursiveDir)%(Filename)%(Extension)')" />
<Exec WorkingDirectory="$(SentryAndroidRoot)" Command="cp sentry/build/libs/sentry*.jar $(SentryAndroidArtifactsDestination)sentry.jar" />
<Exec WorkingDirectory="$(SentryAndroidRoot)" Command="cp -r build/unityMaven $(SentryAndroidArtifactsDestination)" />

<Error Condition="!Exists('$(SentryAndroidArtifactsDestination)')" Text="Failed to build the Android SDK."></Error>
<Error Condition="!Exists('$(SentryAndroidArtifactsDestination)')" Text="Failed to build the Android SDK." />
</Target>

<!-- Build the Sentry Native SDK for Windows: dotnet msbuild /t:BuildWindowsSDK src/Sentry.Unity -->
Expand Down
2 changes: 1 addition & 1 deletion modules/sentry-java
Submodule sentry-java updated 112 files
93 changes: 27 additions & 66 deletions src/Sentry.Unity.Editor/Android/AndroidManifestConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using Sentry.Extensibility;
using Sentry.Unity.Editor.ConfigurationWindow;
Expand All @@ -22,10 +21,6 @@ public class AndroidManifestConfiguration : IPostGenerateGradleAndroidProject
private readonly bool _isDevelopmentBuild;
private readonly ScriptingImplementation _scriptingImplementation;

public const string SDKDependencies = @"
implementation(name: 'sentry-android-ndk-release', ext:'aar')
implementation(name: 'sentry-android-core-release', ext:'aar')";

// Lower levels are called first.
public int callbackOrder => 1;

Expand Down Expand Up @@ -57,11 +52,11 @@ public void OnPostGenerateGradleAndroidProject(string basePath)

var unityProjectPath = Directory.GetParent(Application.dataPath).FullName;
var gradleProjectPath = Directory.GetParent(basePath).FullName;

SetupAndroidSdk(unityProjectPath, gradleProjectPath);
SetupGradle(gradleProjectPath);
SetupSymbolsUpload(unityProjectPath, gradleProjectPath);
SetupProguard(gradleProjectPath);

CopyAndroidSdkToGradleProject(unityProjectPath, gradleProjectPath);
AddAndroidSdkDependencies(gradleProjectPath);
}

internal void ModifyManifest(string basePath)
Expand Down Expand Up @@ -212,14 +207,14 @@ internal void SetupSymbolsUpload(string unityProjectPath, string gradleProjectPa
}
}

internal void SetupProguard(string gradleProjectPath)
private void SetupProguard(string gradleProjectPath)
{
var tool = new ProguardSetup(_logger, gradleProjectPath);
var pluginEnabled = _options is not null && _options.Enabled && _options.AndroidNativeSupportEnabled;
var nativeSupportEnabled = _options is { Enabled: true, AndroidNativeSupportEnabled: true };

try
{
if (pluginEnabled)
if (nativeSupportEnabled)
{
tool.AddToGradleProject();
}
Expand All @@ -230,85 +225,51 @@ internal void SetupProguard(string gradleProjectPath)
}
catch (Exception e)
{
_logger.LogError($"Failed to {(pluginEnabled ? "add" : "remove")} Proguard rules in the gradle project", e);
_logger.LogError($"Failed to {(nativeSupportEnabled ? "add" : "remove")} Proguard rules in the gradle project", e);
}
}

internal void CopyAndroidSdkToGradleProject(string unityProjectPath, string gradlePath)
private void SetupAndroidSdk(string unityProjectPath, string gradleProjectPath)
{
var androidSdkPath = Path.Combine(unityProjectPath, "Packages", SentryPackageInfo.GetName(), "Plugins", "Android", "Sentry~");
var targetPath = Path.Combine(gradlePath, "unityLibrary", "libs");
var sdkSetup = new AndroidSdkSetup(_logger, unityProjectPath, gradleProjectPath);
var nativeSupportEnabled = _options is { Enabled: true, AndroidNativeSupportEnabled: true };

if (_options is { Enabled: true, AndroidNativeSupportEnabled: true })
try
{
if (!Directory.Exists(androidSdkPath))
if (nativeSupportEnabled)
{
throw new DirectoryNotFoundException($"Failed to find the Android SDK at '{androidSdkPath}'.");
sdkSetup.AddAndroidSdk();
}

_logger.LogInfo("Copying the Android SDK to '{0}'.", gradlePath);
foreach (var file in Directory.GetFiles(androidSdkPath))
else
{
var destinationFile = Path.Combine(targetPath, Path.GetFileName(file));
if (!File.Exists(destinationFile))
{
File.Copy(file, destinationFile);
}
sdkSetup.RemoveAndroidSdk();
}
}
else
catch (Exception e)
{
_logger.LogInfo("Removing the Android SDK from the output project.");
foreach (var file in Directory.GetFiles(androidSdkPath))
{
var fileToDelete = Path.Combine(targetPath, Path.GetFileName(file));
if (File.Exists(fileToDelete))
{
File.Delete(fileToDelete);
}
}
_logger.LogError($"Failed to {(nativeSupportEnabled ? "add" : "remove")} the Android SDK to the gradle project", e);
}
}

internal void AddAndroidSdkDependencies(string gradleProjectPath)
private void SetupGradle(string gradleProjectPath)
{
const string regexPattern = @"(dependencies\s\{\n).+";
var gradleSetup = new GradleSetup(_logger, gradleProjectPath);
var nativeSupportEnabled = _options is { Enabled: true, AndroidNativeSupportEnabled: true };

var gradleFilePath = Path.Combine(gradleProjectPath, "unityLibrary", "build.gradle");
if (!File.Exists(gradleFilePath))
{
throw new FileNotFoundException($"Failed to find 'build.gradle' at '{gradleFilePath}'.");
}

var gradle = File.ReadAllText(gradleFilePath);

if (_options is { Enabled: true, AndroidNativeSupportEnabled: true })
try
{
if (gradle.Contains(SDKDependencies))
if (nativeSupportEnabled)
{
_logger.LogDebug("Android SDK dependencies already added. Skipping.");
return;
gradleSetup.UpdateGradleProject();
}

_logger.LogInfo("Adding Android SDK dependencies to 'build.gradle'.");

var regex = new Regex(regexPattern);
var match = regex.Match(gradle);
if (!match.Success)
else
{
throw new ArgumentException($"Failed to add Sentry Android dependencies to 'build.gradle'.\n{gradle}", nameof(gradle));
gradleSetup.ClearGradleProject();
}

File.WriteAllText(gradleFilePath, gradle.Insert(match.Index + match.Length, SDKDependencies));
}
else
catch (Exception e)
{
if (gradle.Contains(SDKDependencies))
{
_logger.LogInfo("Android SDK dependencies have previously been added. Removing them.");

File.WriteAllText(gradleFilePath, gradle.Replace(SDKDependencies, ""));
}
_logger.LogError($"Failed to {(nativeSupportEnabled ? "modify" : "clear")} the 'build.gradle' files.", e);
}
}

Expand Down
69 changes: 69 additions & 0 deletions src/Sentry.Unity.Editor/Android/AndroidSdkSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.IO;
using Sentry.Extensibility;

namespace Sentry.Unity.Editor.Android
{
internal class AndroidSdkSetup
{
private readonly IDiagnosticLogger _logger;
private readonly string _androidSdkPath;
private readonly string _targetAndroidSdkPath;

public AndroidSdkSetup(IDiagnosticLogger logger, string unityProjectPath, string gradleProjectPath)
{
_logger = logger;
_androidSdkPath = Path.Combine(unityProjectPath, "Packages", SentryPackageInfo.GetName(), "Plugins", "Android", "Sentry~");
_targetAndroidSdkPath = Path.Combine(gradleProjectPath, "unityLibrary", "android-sdk-repository");
}

internal void AddAndroidSdk()
{
if (Directory.Exists(_targetAndroidSdkPath))
{
_logger.LogDebug("Android SDK already detected at '{0}'. Skip copying.", _targetAndroidSdkPath);
return;
}

if (!Directory.Exists(_androidSdkPath))
{
throw new DirectoryNotFoundException($"Failed to find the Android SDK at '{_androidSdkPath}'.");
}

_logger.LogInfo("Copying the Android SDK to '{0}'.", _targetAndroidSdkPath);
CopyDirectory(_androidSdkPath, _targetAndroidSdkPath);
}

public void RemoveAndroidSdk()
{
if (Directory.Exists(_targetAndroidSdkPath))
{
_logger.LogInfo("Removing the Android SDK from the output project.");
Directory.Delete(_targetAndroidSdkPath, true);
}
}

private static void CopyDirectory(string sourceDirectory, string destinationDirectory)
{
var directory = new DirectoryInfo(sourceDirectory);
if (!directory.Exists)
{
throw new DirectoryNotFoundException($"Source directory not found: {directory.FullName}");
}

var subDirectories = directory.GetDirectories();
Directory.CreateDirectory(destinationDirectory);

foreach (var file in directory.GetFiles())
{
var targetFilePath = Path.Combine(destinationDirectory, file.Name);
file.CopyTo(targetFilePath);
}

foreach (var subDirectory in subDirectories)
{
var newDestinationDir = Path.Combine(destinationDirectory, subDirectory.Name);
CopyDirectory(subDirectory.FullName, newDestinationDir);
}
}
}
}
Loading