Skip to content

Commit

Permalink
Release: v14.0.0 (#533)
Browse files Browse the repository at this point in the history
* fix: add support for newer gradle versions (#512)

* feat: attach w3c header (#481)

* feat: add android feature flag

* fix: test cases

* fix: test cases

* fix: test cases

* fix: test cases

* fix: add more test cases

* fix: add more test cases

* fix: add more test cases

* fix: add more test cases

* Release: v14.0.0 (#532)

* chore(android): bump sdk to v14.0.0

* chore(ios): bump sdk to v14.0.0

* Release: v14.0.0

* Release: v14.0.0

* Release: v14.0.0

* chore: change release date (#535)

---------

Co-authored-by: kholood <[email protected]>
  • Loading branch information
ahmedAlaaInstabug and kholood-ea authored Nov 18, 2024
1 parent c699efc commit 08b600e
Show file tree
Hide file tree
Showing 41 changed files with 1,113 additions and 94 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## [14.0.0](https://github.com/Instabug/Instabug-Flutter/compare/v13.4.0...v14.0.0) (November 18, 2024)

### Added

- Add support for tracing network requests from Instabug to services like Datadog and New Relic ([#481](https://github.com/Instabug/Instabug-Flutter/pull/481)).

### Changed

- Bump Instabug Android SDK to v14.0.0 ([#532](https://github.com/Instabug/Instabug-Flutter/pull/532)). [See release notes](https://github.com/Instabug/Instabug-Android/releases/tag/v14.0.0).
- Bump Instabug iOS SDK to v14.0.0 ([#532](https://github.com/Instabug/Instabug-Flutter/pull/532)). [See release notes](https://github.com/Instabug/Instabug-iOS/releases/tag/14.0.0),

## [13.4.0](https://github.com/Instabug/Instabug-Flutter/compare/v13.3.0...v13.4.0) (September 29, 2024)

### Added
Expand Down
12 changes: 8 additions & 4 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
group 'com.instabug.flutter'
version '13.4.0'
version '14.0.0'

buildscript {
repositories {
Expand All @@ -22,7 +22,10 @@ rootProject.allprojects {
apply plugin: 'com.android.library'

android {
compileSdkVersion 28
if (project.android.hasProperty("namespace")) {
namespace "com.instabug.flutter"
}
compileSdkVersion 33

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand All @@ -41,10 +44,11 @@ android {
}

dependencies {
api 'com.instabug.library:instabug:13.4.1'

api 'com.instabug.library:instabug:14.0.0'
testImplementation 'junit:junit:4.13.2'
testImplementation "org.mockito:mockito-inline:3.12.1"
testImplementation "io.mockk:mockk:1.13.13"

}

// add upload_symbols task
Expand Down
3 changes: 1 addition & 2 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.instabug.flutter">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application>
<meta-data
Expand Down
63 changes: 53 additions & 10 deletions android/src/main/java/com/instabug/flutter/modules/ApmApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@
import com.instabug.apm.configuration.cp.FeatureAvailabilityCallback;
import com.instabug.apm.model.ExecutionTrace;
import com.instabug.apm.networking.APMNetworkLogger;
import com.instabug.apm.networkinterception.cp.APMCPNetworkLog;
import com.instabug.flutter.generated.ApmPigeon;
import com.instabug.flutter.util.Reflection;
import com.instabug.flutter.util.ThreadManager;
import com.instabug.apm.networkinterception.cp.APMCPNetworkLog;

import io.flutter.plugin.common.BinaryMessenger;

import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;

import java.lang.reflect.Method;
Expand Down Expand Up @@ -210,18 +209,62 @@ public void networkLogAndroid(@NonNull Map<String, Object> data) {
if (data.containsKey("serverErrorMessage")) {
serverErrorMessage = (String) data.get("serverErrorMessage");
}
Boolean isW3cHeaderFound = null;
Number partialId = null;
Number networkStartTimeInSeconds = null;
String w3CGeneratedHeader = null;
String w3CCaughtHeader = null;

if (data.containsKey("isW3cHeaderFound")) {
isW3cHeaderFound = (Boolean) data.get("isW3cHeaderFound");
}

if (data.containsKey("partialId")) {


partialId = ((Number) data.get("partialId"));

Method method = Reflection.getMethod(Class.forName("com.instabug.apm.networking.APMNetworkLogger"), "log", long.class, long.class, String.class, String.class, long.class, String.class, String.class, String.class, String.class, String.class, long.class, int.class, String.class, String.class, String.class, String.class, APMCPNetworkLog.W3CExternalTraceAttributes.class);
if (method != null) {
method.invoke(apmNetworkLogger, requestStartTime, requestDuration, requestHeaders, requestBody, requestBodySize, requestMethod, requestUrl, requestContentType, responseHeaders, responseBody, responseBodySize, statusCode, responseContentType, errorMessage, gqlQueryName, serverErrorMessage, null);
} else {
Log.e(TAG, "APMNetworkLogger.log was not found by reflection");
}
if (data.containsKey("networkStartTimeInSeconds")) {
networkStartTimeInSeconds = ((Number) data.get("networkStartTimeInSeconds"));
}

} catch (Exception e) {
e.printStackTrace();
if (data.containsKey("w3CGeneratedHeader")) {

w3CGeneratedHeader = (String) data.get("w3CGeneratedHeader");


}
if (data.containsKey("w3CCaughtHeader")) {
w3CCaughtHeader = (String) data.get("w3CCaughtHeader");

}


APMCPNetworkLog.W3CExternalTraceAttributes w3cExternalTraceAttributes =
null;
if (isW3cHeaderFound != null) {
w3cExternalTraceAttributes = new APMCPNetworkLog.W3CExternalTraceAttributes(
isW3cHeaderFound, partialId == null ? null : partialId.longValue(),
networkStartTimeInSeconds == null ? null : networkStartTimeInSeconds.longValue(),
w3CGeneratedHeader, w3CCaughtHeader

);
}

Method method = Reflection.getMethod(Class.forName("com.instabug.apm.networking.APMNetworkLogger"), "log", long.class, long.class, String.class, String.class, long.class, String.class, String.class, String.class, String.class, String.class, long.class, int.class, String.class, String.class, String.class, String.class, APMCPNetworkLog.W3CExternalTraceAttributes.class);
if (method != null) {
method.invoke(apmNetworkLogger, requestStartTime, requestDuration, requestHeaders, requestBody, requestBodySize, requestMethod, requestUrl, requestContentType, responseHeaders, responseBody, responseBodySize, statusCode, responseContentType, errorMessage, gqlQueryName, serverErrorMessage, w3cExternalTraceAttributes);
} else {
Log.e(TAG, "APMNetworkLogger.log was not found by reflection");
}

} catch(Exception e){
e.printStackTrace();
}
}
}




@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
import com.instabug.flutter.util.ArgsRegistry;
import com.instabug.flutter.util.Reflection;
import com.instabug.flutter.util.ThreadManager;
import com.instabug.library.internal.crossplatform.CoreFeature;
import com.instabug.library.internal.crossplatform.CoreFeaturesState;
import com.instabug.library.internal.crossplatform.FeaturesStateListener;
import com.instabug.library.internal.crossplatform.InternalCore;
import com.instabug.library.Feature;
import com.instabug.library.Instabug;
import com.instabug.library.InstabugColorTheme;
Expand Down Expand Up @@ -48,14 +52,19 @@ public class InstabugApi implements InstabugPigeon.InstabugHostApi {
private final Callable<Bitmap> screenshotProvider;
private final InstabugCustomTextPlaceHolder placeHolder = new InstabugCustomTextPlaceHolder();

private final InstabugPigeon.FeatureFlagsFlutterApi featureFlagsFlutterApi;

public static void init(BinaryMessenger messenger, Context context, Callable<Bitmap> screenshotProvider) {
final InstabugApi api = new InstabugApi(context, screenshotProvider);
final InstabugPigeon.FeatureFlagsFlutterApi flutterApi = new InstabugPigeon.FeatureFlagsFlutterApi(messenger);

final InstabugApi api = new InstabugApi(context, screenshotProvider, flutterApi);
InstabugPigeon.InstabugHostApi.setup(messenger, api);
}

public InstabugApi(Context context, Callable<Bitmap> screenshotProvider) {
public InstabugApi(Context context, Callable<Bitmap> screenshotProvider, InstabugPigeon.FeatureFlagsFlutterApi featureFlagsFlutterApi) {
this.context = context;
this.screenshotProvider = screenshotProvider;
this.featureFlagsFlutterApi = featureFlagsFlutterApi;
}

@VisibleForTesting
Expand Down Expand Up @@ -437,6 +446,48 @@ public void networkLog(@NonNull Map<String, Object> data) {
}
}

@Override
public void registerFeatureFlagChangeListener() {

try {
InternalCore.INSTANCE._setFeaturesStateListener(new FeaturesStateListener() {
@Override
public void invoke(@NonNull CoreFeaturesState featuresState) {
ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
featureFlagsFlutterApi.onW3CFeatureFlagChange(featuresState.isW3CExternalTraceIdEnabled(),
featuresState.isAttachingGeneratedHeaderEnabled(),
featuresState.isAttachingCapturedHeaderEnabled(),
new InstabugPigeon.FeatureFlagsFlutterApi.Reply<Void>() {
@Override
public void reply(Void reply) {

}
});
}
});
}

});
} catch (Exception e) {
e.printStackTrace();
}

}

@NonNull
@Override
public Map<String, Boolean> isW3CFeatureFlagsEnabled() {
Map<String, Boolean> params = new HashMap<String, Boolean>();
params.put("isW3cExternalTraceIDEnabled", InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_EXTERNAL_TRACE_ID));
params.put("isW3cExternalGeneratedHeaderEnabled", InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_GENERATED_HEADER));
params.put("isW3cCaughtHeaderEnabled", InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_CAPTURED_HEADER));


return params;
}

@Override
public void willRedirectToStore() {
Instabug.willRedirectToStore();
Expand Down
13 changes: 13 additions & 0 deletions android/src/test/java/com/instabug/flutter/ApmApiTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
package com.instabug.flutter;

import static com.instabug.flutter.util.GlobalMocks.reflected;
import static com.instabug.flutter.util.MockResult.makeResult;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockConstruction;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.instabug.apm.APM;
import com.instabug.apm.InternalAPM;
import com.instabug.apm.configuration.cp.APMFeature;
Expand Down
57 changes: 51 additions & 6 deletions android/src/test/java/com/instabug/flutter/InstabugApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import static io.mockk.MockKKt.every;
import static io.mockk.MockKKt.mockkObject;

import io.mockk.*;

import android.app.Application;
import android.graphics.Bitmap;
import android.net.Uri;

import com.instabug.apm.InternalAPM;
import com.instabug.bug.BugReporting;
import com.instabug.flutter.generated.InstabugPigeon;
import com.instabug.flutter.modules.InstabugApi;
Expand All @@ -36,9 +42,15 @@
import com.instabug.library.ReproConfigurations;
import com.instabug.library.ReproMode;
import com.instabug.library.featuresflags.model.IBGFeatureFlag;
import com.instabug.library.internal.crossplatform.CoreFeature;
import com.instabug.library.internal.crossplatform.FeaturesStateListener;
import com.instabug.library.internal.crossplatform.InternalCore;
import com.instabug.library.featuresflags.model.IBGFeatureFlag;
import com.instabug.library.invocation.InstabugInvocationEvent;
import com.instabug.library.model.NetworkLog;
import com.instabug.library.ui.onboarding.WelcomeMessage;
import com.instabug.survey.Surveys;
import com.instabug.survey.callbacks.OnShowCallback;

import org.json.JSONObject;
import org.junit.After;
Expand All @@ -56,9 +68,16 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;

import io.flutter.plugin.common.BinaryMessenger;
import kotlin.jvm.functions.Function1;

import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.mockito.verification.VerificationMode;
import org.mockito.verification.VerificationMode;

public class InstabugApiTest {
Expand All @@ -69,11 +88,15 @@ public class InstabugApiTest {
private MockedStatic<BugReporting> mBugReporting;
private MockedConstruction<InstabugCustomTextPlaceHolder> mCustomTextPlaceHolder;
private MockedStatic<InstabugPigeon.InstabugHostApi> mHostApi;

private InternalCore internalCore;
@Before
public void setUp() throws NoSuchMethodException {
mCustomTextPlaceHolder = mockConstruction(InstabugCustomTextPlaceHolder.class);
api = spy(new InstabugApi(mContext, screenshotProvider));
internalCore=spy(InternalCore.INSTANCE);

BinaryMessenger mMessenger = mock(BinaryMessenger.class);
final InstabugPigeon.FeatureFlagsFlutterApi flutterApi = new InstabugPigeon.FeatureFlagsFlutterApi(mMessenger);
api = spy(new InstabugApi(mContext, screenshotProvider, flutterApi));
mInstabug = mockStatic(Instabug.class);
mBugReporting = mockStatic(BugReporting.class);
mHostApi = mockStatic(InstabugPigeon.InstabugHostApi.class);
Expand All @@ -87,6 +110,7 @@ public void cleanUp() {
mBugReporting.close();
mHostApi.close();
GlobalMocks.close();

}

@Test
Expand Down Expand Up @@ -349,11 +373,11 @@ public void testClearAllExperiments() {

@Test
public void testAddFeatureFlags() {
Map<String,String > featureFlags = new HashMap<>();
featureFlags.put("key1","variant1");
Map<String, String> featureFlags = new HashMap<>();
featureFlags.put("key1", "variant1");
api.addFeatureFlags(featureFlags);
List<IBGFeatureFlag> flags=new ArrayList<IBGFeatureFlag>();
flags.add(new IBGFeatureFlag("key1","variant1"));
List<IBGFeatureFlag> flags = new ArrayList<IBGFeatureFlag>();
flags.add(new IBGFeatureFlag("key1", "variant1"));
mInstabug.verify(() -> Instabug.addFeatureFlags(flags));
}

Expand Down Expand Up @@ -598,4 +622,25 @@ public void testWillRedirectToStore() {
api.willRedirectToStore();
mInstabug.verify(Instabug::willRedirectToStore);
}


@Test
public void isW3CFeatureFlagsEnabled() {
mockkObject(new InternalCore[]{InternalCore.INSTANCE},false);
Random random=new Random();
Boolean isW3cExternalGeneratedHeaderEnabled = random.nextBoolean();
Boolean isW3cExternalTraceIDEnabled = random.nextBoolean();
Boolean isW3cCaughtHeaderEnabled = random.nextBoolean();

every((Function1<MockKMatcherScope, Boolean>) mockKMatcherScope -> InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_GENERATED_HEADER)).returns(isW3cExternalGeneratedHeaderEnabled);
every((Function1<MockKMatcherScope, Boolean>) mockKMatcherScope -> InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_EXTERNAL_TRACE_ID)).returns(isW3cExternalTraceIDEnabled);
every((Function1<MockKMatcherScope, Boolean>) mockKMatcherScope -> InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_CAPTURED_HEADER)).returns(isW3cCaughtHeaderEnabled);


Map<String, Boolean> flags = api.isW3CFeatureFlagsEnabled();
assertEquals(isW3cExternalGeneratedHeaderEnabled, flags.get("isW3cExternalGeneratedHeaderEnabled"));
assertEquals(isW3cExternalTraceIDEnabled, flags.get("isW3cExternalTraceIDEnabled"));
assertEquals(isW3cCaughtHeaderEnabled, flags.get("isW3cCaughtHeaderEnabled"));

}
}
7 changes: 4 additions & 3 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion flutter.compileSdkVersion
compileSdkVersion 34
ndkVersion flutter.ndkVersion

compileOptions {
Expand All @@ -44,8 +44,8 @@ android {

defaultConfig {
applicationId "com.instabug.flutter.example"
minSdkVersion flutter.minSdkVersion
targetSdkVersion 30
minSdkVersion 21
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand All @@ -59,6 +59,7 @@ android {
signingConfig signingConfigs.debug
}
}
namespace 'com.instabug.flutter.example'

configurations.all {
resolutionStrategy.force 'org.hamcrest:hamcrest-core:1.3'
Expand Down
3 changes: 1 addition & 2 deletions example/android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.instabug.flutter.example">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
Expand Down
Loading

0 comments on commit 08b600e

Please sign in to comment.