Skip to content
Open
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
3 changes: 1 addition & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {

android {
namespace 'io.middleware.android.sample'
compileSdk 34
compileSdk 35
def secretPropertiesFile = rootProject.file("secrets.properties")
def secretProperties = new Properties()
secretProperties.load(new FileInputStream(secretPropertiesFile))
Expand Down Expand Up @@ -48,7 +48,6 @@ android {
}

dependencies {
implementation 'io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:1.32.1-alpha'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.10.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '8.1.2' apply false
id 'com.android.library' version '8.1.2' apply false
id 'com.android.application' version '8.6.1' apply false
id 'com.android.library' version '8.6.1' apply false
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Mon Oct 30 17:29:45 IST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
6 changes: 3 additions & 3 deletions sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ plugins {
id 'com.android.library'
id "com.vanniktech.maven.publish" version "0.34.0"
}

mavenPublishing {
publishToMavenCentral(true)
signAllPublications()

coordinates("io.github.middleware-labs", "android-sdk", "2.0.8-rn")
coordinates("io.github.middleware-labs", "android-sdk", "2.0.9-rn")

pom {
name = "Middleware Android RUM SDK"
Expand Down Expand Up @@ -37,7 +36,7 @@ mavenPublishing {
}
android {
namespace 'io.middleware.android.sdk'
compileSdk 34
compileSdk 35

defaultConfig {
minSdk 21
Expand Down Expand Up @@ -86,6 +85,7 @@ dependencies {
implementation 'org.apache.commons:commons-lang3:3.13.0'
implementation 'commons-codec:commons-codec:1.16.0'
implementation 'androidx.annotation:annotation-jvm:1.9.1'
implementation 'androidx.compose.ui:ui-android:1.9.5'
implementation 'androidx.fragment:fragment:1.8.6'
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4"
testImplementation('org.mockito:mockito-core:5.7.0')
Expand Down
34 changes: 11 additions & 23 deletions sdk/src/main/java/io/middleware/android/sdk/Middleware.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.location.Location;
import android.os.Build;
import android.os.Handler;
Expand All @@ -34,7 +35,7 @@
import io.middleware.android.sdk.core.models.NativeRumSessionId;
import io.middleware.android.sdk.core.replay.MiddlewareRecorder;
import io.middleware.android.sdk.core.replay.ReplayRecording;
import io.middleware.android.sdk.core.replay.v2.ActivityCallbacks;
import io.middleware.android.sdk.core.replay.v2.LifecycleManager;
import io.middleware.android.sdk.core.replay.v2.MiddlewareScreenshotManager;
import io.middleware.android.sdk.extractors.RumResponseAttributesExtractor;
import io.middleware.android.sdk.interfaces.IMiddleware;
Expand Down Expand Up @@ -94,28 +95,26 @@ public static MiddlewareBuilder builder() {
// for testing purposes
public static Middleware initialize(
MiddlewareBuilder builder,
Application application,
Context context,
Function<Application, CurrentNetworkProvider> currentNetworkProviderFactory) {
if (INSTANCE != null) {
Log.w(LOG_TAG, "Singleton Middleware instance has already been initialized.");
return INSTANCE;
}

rumInitializer = new RumInitializer(builder, application, startupTimer);
final LifecycleManager lifecycleManager = new LifecycleManager(context.getApplicationContext(),
(context instanceof Activity)
? (Activity) context
: null);
rumInitializer = new RumInitializer(builder, context, startupTimer);
INSTANCE = rumInitializer.initialize(currentNetworkProviderFactory, Looper.getMainLooper());
LOGGER = INSTANCE.getOpenTelemetry().getLogsBridge()
.loggerBuilder(builder.serviceName)
.build();
if (builder.isRecordingEnabled()) {
Log.d(LOG_TAG, "Session recording enabled, waiting layout to get attached.");
middlewareScreenshotManager = new MiddlewareScreenshotManager(
System.currentTimeMillis(),
builder.target,
builder.rumAccessToken
builder, lifecycleManager
);
application.registerActivityLifecycleCallbacks(
new ActivityCallbacks(middlewareScreenshotManager))
;
}
Log.i(LOG_TAG, "Middleware RUM monitoring initialized with session ID: " + INSTANCE.getRumSessionId());
return INSTANCE;
Expand Down Expand Up @@ -151,23 +150,12 @@ public MiddlewareRecorder getRecorder() {
return new MiddlewareRecorder(this);
}

public void startNativeRecording(Activity activity) {
public void startNativeRecording() {
if (middlewareScreenshotManager != null) {
middlewareScreenshotManager.setActivity(activity);
middlewareScreenshotManager.start(System.currentTimeMillis());
}
}

/**
* @return {@code true} if the recording started successfully.
*/
public boolean startRecording() {
if (middlewareScreenshotManager != null) {
middlewareScreenshotManager.start();
return true;
}
return false;
}

/**
* @return @{code true} if session recording stopped successfully.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static io.middleware.android.sdk.utils.Constants.LOG_TAG;

import android.app.Application;
import android.content.Context;
import android.util.Log;

import androidx.annotation.Nullable;
Expand All @@ -12,6 +13,9 @@

import io.middleware.android.sdk.Middleware;
import io.middleware.android.sdk.core.models.ConfigFlags;
import io.middleware.android.sdk.core.replay.RecordingFrequency;
import io.middleware.android.sdk.core.replay.RecordingQuality;
import io.middleware.android.sdk.core.replay.v2.RecordingOptions;
import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider;
import io.opentelemetry.api.common.Attributes;

Expand All @@ -33,6 +37,10 @@ public final class MiddlewareBuilder {
public Attributes globalAttributes = Attributes.empty();
@Nullable
public String deploymentEnvironment;
public RecordingOptions recordingOptions = new RecordingOptions.Builder()
.setFrequency(RecordingFrequency.LOW)
.setQuality(RecordingQuality.LOW)
.build();

/**
* Sets the application name that will be used to identify your application in the Middleware RUM
Expand Down Expand Up @@ -198,12 +206,12 @@ public MiddlewareBuilder setDeploymentEnvironment(String environment) {
* Middleware#getInstance()}. If there was a global {@link Middleware} instance configured before,
* this method does not initialize a new one and simply returns the existing instance.
*/
public Middleware build(Application application) {
public Middleware build(Context context) {
if (rumAccessToken == null || target == null || projectName == null || serviceName == null) {
throw new IllegalStateException(
"You must provide a rumAccessToken, target, projectName and an serviceName to create a valid Config instance.");
}
return Middleware.initialize(this, application, CurrentNetworkProvider::createAndStart);
return Middleware.initialize(this, context, CurrentNetworkProvider::createAndStart);
}

public boolean isAnrDetectionEnabled() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import static io.opentelemetry.semconv.ResourceAttributes.DEPLOYMENT_ENVIRONMENT;
import static io.opentelemetry.semconv.ResourceAttributes.SERVICE_NAME;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Looper;
import android.util.Log;

Expand Down Expand Up @@ -63,9 +65,15 @@ public class RumInitializer implements IRum {
private final AppStartupTimer appStartupTimer;
private final InitializationEvents initializerEvent;

public RumInitializer(MiddlewareBuilder builder, Application application, AppStartupTimer appStartupTimer) {
public RumInitializer(MiddlewareBuilder builder, Context context, AppStartupTimer appStartupTimer) {
this.builder = builder;
this.application = application;
if (context instanceof Activity) {
this.application = ((Activity) context).getApplication();
} else if (context instanceof Application) {
this.application = (Application) context;
} else {
this.application = (Application) context.getApplicationContext();
}
this.appStartupTimer = appStartupTimer;
this.initializerEvent = new InitializationEvents(appStartupTimer);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.middleware.android.sdk.core.replay;

/**
* Defines how often screenshots are captured.
*/
public enum RecordingFrequency {
LOW(1000L), // 1 FPS
STANDARD(330L), // ~3 FPS
HIGH(100L); // 10 FPS

private final long intervalMs;

RecordingFrequency(long intervalMs) {
this.intervalMs = intervalMs;
}

public long getIntervalMs() {
return intervalMs;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.middleware.android.sdk.core.replay;

public enum RecordingQuality {
LOW(25),
MEDIUM(50),
HIGH(75);

private final int value;

RecordingQuality(int value) {
this.value = value;
}

public int getValue() {
return value;
}
}

This file was deleted.

Loading
Loading