Skip to content

Add auto start instrumentation #2098

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

priettt
Copy link
Contributor

@priettt priettt commented Apr 15, 2025

Goal

Add ASM instrumentation to start the Embrace SDK automatically.

  • Created AutoStartInstrumentationHook, which will be called from the instrumented code.
    • I decided to create this class instead of calling Embrace.start() directly, so the code goes through a different path. We could even add telemetry to log if the app was autostarted if we wanted to.
    • This class was added to the Embrace API like the rest of the hooks in the embracesdk package.
  • Use ASM to insert a call to AutoStartInstrumentationHook._preOnCreate() in any onCreate method in any class that extends Application.
  • Added a flag to disable auto start instrumentation, though it's turned on by default.

Testing

Added a unit test, a InstrumentedBytecodeTestCase, and a BytecodeInstrumentationTest, similar to what we use to test other instrumentation.

@priettt priettt force-pushed the priettt/autoInstrumentStart branch from 2d8e9d5 to 3108bb5 Compare April 15, 2025 17:41
Copy link
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@@ -1,3 +1,7 @@
public final class io/embrace/android/embracesdk/AutoStartInstrumentationHook {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this would be under an internal package (but have public visibility) and the function would not contain an underscore

* @hide
*/
@InternalApi
public final class AutoStartInstrumentationHook {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Java?

}
}

private static void logError(@NonNull Throwable throwable) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't do anything if the SDK isn't started so IMO could be deleted, and we just swallow any unexpected exception

@@ -42,6 +42,11 @@ abstract class EmbraceBytecodeInstrumentation @Inject internal constructor(objec
val firebasePushNotificationsEnabled: Property<Boolean> =
objectFactory.property(Boolean::class.java)

/**
* Whether Embrace should automatically start in the Application class. Defaults to true.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defaulting this to true feels like a breaking change as folks will already have setup their own place where Embrace is initialized, which will probably be in a different location to where bytecode instrumentation assumes

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably default to false initially until we do a major version bump. But whether we ever flip it to true is probably something product should decide. Having the "no code start" opt-in-able via a gradle property already seems like a big win.

/**
* Visits the Application class and returns an [ApplicationMethodAdapter] for the onCreate method.
*/
class ApplicationClassAdapter(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This current implementation only works if an Application class exists and if the onCreate function has an override. I think that would be a reasonable approach but we will need to document this on the docs site (along with the new gradle DSL property)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another approach would be to stick this in a content provider. But yeah I'd just go with this first and document it - this seems much less intrusive and likely covers most production cases anyway.

* Whether auto-start instrumentation should be enabled or not
*/
@Json(name = "auto_start")
val autoStart: Boolean? = null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this required as well as a property on the extension?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I would just go with property so there isn't two sources of truth. Going with the property also allows customers to use the SDK without a config file, which will make trying it out easier.

* @hide
*/
@InternalApi
public final class AutoStartInstrumentationHook {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really instrumentation, but starting the SDK, so maybe call it AutoStartSdkHook or something? And are we still using the word "hook"

And technically this functionality is just wrapping SDK start, and the "auto" part is the result of doing the bytecode instrumentation. Maybe you can even call it SdkInitialization or something, as I think we'll want to add the applicationInitStart/End hooks in there too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably worth looking at the conventions I've adopted on this integration branch for some of the bytecode instrumentation. Once 7.3.0 is out I'll merge that down: #2103

Copy link
Contributor

This PR is stale because it has been open 20 days with no activity. Remove stale label or comment or this PR will be closed in 10 days.

@github-actions github-actions bot added the stale label May 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants