Skip to content

[INSD-9768] Fix Channel Method Calls on Background Threads #370

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 3 commits into from
Jul 4, 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
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,22 @@

### Fixed

- Fix an issue with the `onInvoke` callback not being called and causing `Instabug.show` to break on Android ([#369](https://github.com/Instabug/Instabug-Flutter/pull/369)).
- Fix an issue that caused APIs that return a value or invoke a callback break on Android in some versions of Flutter ([#370](https://github.com/Instabug/Instabug-Flutter/pull/370), [#369](https://github.com/Instabug/Instabug-Flutter/pull/369)).

Below is a list of all the affected APIs:

- `APM.startExecutionTrace`
- `BugReporting.setOnInvokeCallback`
- `BugReporting.setOnDismissCallback`
- `Instabug.getTags`
- `Instabug.getUserAttributeForKey`
- `Instabug.getUserAttributes`
- `Replies.getUnreadRepliesCount`
- `Replies.hasChats`
- `Replies.setOnNewReplyReceivedCallback`
- `Surveys.hasRespondToSurvey`
- `Surveys.setOnShowCallback`
- `Surveys.setOnDismissCallback`

## [11.12.0](https://github.com/Instabug/Instabug-Flutter/compare/v11.10.1...v11.12.0) (May 30, 2023)

Expand Down
23 changes: 20 additions & 3 deletions android/src/main/java/com/instabug/flutter/modules/ApmApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,30 @@ public void run() {
ExecutionTrace trace = APM.startExecutionTrace(name);
if (trace != null) {
traces.put(id, trace);
result.success(id);

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(id);
}
});
} else {
result.success(null);
ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(null);
}
});
}
} catch (Exception e) {
e.printStackTrace();
result.success(null);

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(null);
}
});
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,14 @@ public void bindOnDismissCallback() {
BugReporting.setOnDismissCallback(new OnSdkDismissCallback() {
@Override
public void call(DismissType dismissType, ReportType reportType) {
flutterApi.onSdkDismiss(dismissType.toString(), reportType.toString(), new BugReportingPigeon.BugReportingFlutterApi.Reply<Void>() {
ThreadManager.runOnMainThread(new Runnable() {
@Override
public void reply(Void reply) {
public void run() {
flutterApi.onSdkDismiss(dismissType.toString(), reportType.toString(), new BugReportingPigeon.BugReportingFlutterApi.Reply<Void>() {
@Override
public void reply(Void reply) {
}
});
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,14 @@ public void getTags(InstabugPigeon.Result<List<String>> result) {
new Runnable() {
@Override
public void run() {
result.success(Instabug.getTags());
final List<String> tags = Instabug.getTags();

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(tags);
}
});
}
}
);
Expand Down Expand Up @@ -234,7 +241,14 @@ public void getUserAttributeForKey(@NonNull String key, InstabugPigeon.Result<St
new Runnable() {
@Override
public void run() {
result.success(Instabug.getUserAttribute(key));
final String attribute = Instabug.getUserAttribute(key);

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(attribute);
}
});
}
}
);
Expand All @@ -246,7 +260,14 @@ public void getUserAttributes(InstabugPigeon.Result<Map<String, String>> result)
new Runnable() {
@Override
public void run() {
result.success(Instabug.getAllUserAttributes());
final Map<String, String> attributes = Instabug.getAllUserAttributes();

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(attributes);
}
});
}
}
);
Expand Down
27 changes: 23 additions & 4 deletions android/src/main/java/com/instabug/flutter/modules/RepliesApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ public void getUnreadRepliesCount(RepliesPigeon.Result<Long> result) {
new Runnable() {
@Override
public void run() {
result.success((long) Replies.getUnreadRepliesCount());
final long count = Replies.getUnreadRepliesCount();

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(count);
}
});
}
}
);
Expand All @@ -64,7 +71,14 @@ public void hasChats(RepliesPigeon.Result<Boolean> result) {
new Runnable() {
@Override
public void run() {
result.success(Replies.hasChats());
final boolean hasChats = Replies.hasChats();

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(hasChats);
}
});
}
}
);
Expand All @@ -75,9 +89,14 @@ public void bindOnNewReplyCallback() {
Replies.setOnNewReplyReceivedCallback(new Runnable() {
@Override
public void run() {
flutterApi.onNewReply(new RepliesPigeon.RepliesFlutterApi.Reply<Void>() {
ThreadManager.runOnMainThread(new Runnable() {
@Override
public void reply(Void reply) {
public void run() {
flutterApi.onNewReply(new RepliesPigeon.RepliesFlutterApi.Reply<Void>() {
@Override
public void reply(Void reply) {
}
});
}
});
}
Expand Down
33 changes: 27 additions & 6 deletions android/src/main/java/com/instabug/flutter/modules/SurveysApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,13 @@ public void hasRespondedToSurvey(@NonNull String surveyToken, SurveysPigeon.Resu
@Override
public void run() {
final boolean hasResponded = Surveys.hasRespondToSurvey(surveyToken);
result.success(hasResponded);

ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(hasResponded);
}
});
}
}
);
Expand All @@ -88,7 +94,12 @@ public void run() {
titles.add(survey.getTitle());
}

result.success(titles);
ThreadManager.runOnMainThread(new Runnable() {
@Override
public void run() {
result.success(titles);
}
});
}
}
);
Expand All @@ -99,9 +110,14 @@ public void bindOnShowSurveyCallback() {
Surveys.setOnShowCallback(new OnShowCallback() {
@Override
public void onShow() {
flutterApi.onShowSurvey(new SurveysPigeon.SurveysFlutterApi.Reply<Void>() {
ThreadManager.runOnMainThread(new Runnable() {
@Override
public void reply(Void reply) {
public void run() {
flutterApi.onShowSurvey(new SurveysPigeon.SurveysFlutterApi.Reply<Void>() {
@Override
public void reply(Void reply) {
}
});
}
});
}
Expand All @@ -113,9 +129,14 @@ public void bindOnDismissSurveyCallback() {
Surveys.setOnDismissCallback(new OnDismissCallback() {
@Override
public void onDismiss() {
flutterApi.onDismissSurvey(new SurveysPigeon.SurveysFlutterApi.Reply<Void>() {
ThreadManager.runOnMainThread(new Runnable() {
@Override
public void reply(Void reply) {
public void run() {
flutterApi.onDismissSurvey(new SurveysPigeon.SurveysFlutterApi.Reply<Void>() {
@Override
public void reply(Void reply) {
}
});
}
});
}
Expand Down
15 changes: 10 additions & 5 deletions android/src/test/java/com/instabug/flutter/util/GlobalMocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.json.JSONObject;
import org.mockito.MockedStatic;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.lang.reflect.Method;

Expand All @@ -26,13 +27,17 @@ public static void setUp() throws NoSuchMethodException {

// ThreadManager mock
threadManager = mockStatic(ThreadManager.class);
Answer threadAnswer = (InvocationOnMock invocation) -> {
Runnable runnable = invocation.getArgument(0);
runnable.run();
return null;
};
threadManager
.when(() -> ThreadManager.runOnBackground(any(Runnable.class)))
.thenAnswer((InvocationOnMock invocation) -> {
Runnable runnable = invocation.getArgument(0);
runnable.run();
return null;
});
.thenAnswer(threadAnswer);
threadManager
.when(() -> ThreadManager.runOnMainThread(any(Runnable.class)))
.thenAnswer(threadAnswer);

// Reflection mock
reflection = mockStatic(Reflection.class);
Expand Down