-
Notifications
You must be signed in to change notification settings - Fork 617
Fix FIAM ANR Issue 1430 #1488
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
Fix FIAM ANR Issue 1430 #1488
Changes from all commits
c153bf5
cf9b67a
462d158
3f7a5c8
918b1fb
cc0403a
ffeb757
b059dc8
61f891a
fb6c5ba
bd85fa4
fe23cb0
d538bab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,11 @@ | |
|
||
package com.google.firebase.inappmessaging.internal; | ||
|
||
import android.text.TextUtils; | ||
import androidx.annotation.VisibleForTesting; | ||
import com.google.android.gms.tasks.Task; | ||
import com.google.firebase.iid.FirebaseInstanceId; | ||
import com.google.firebase.iid.InstanceIdResult; | ||
import com.google.firebase.inappmessaging.CommonTypesProto.TriggeringCondition; | ||
import com.google.firebase.inappmessaging.internal.injection.qualifiers.AppForeground; | ||
import com.google.firebase.inappmessaging.internal.injection.qualifiers.ProgrammaticTrigger; | ||
|
@@ -36,6 +40,7 @@ | |
import io.reactivex.functions.Consumer; | ||
import io.reactivex.functions.Function; | ||
import java.util.Locale; | ||
import javax.annotation.Nullable; | ||
import javax.inject.Inject; | ||
|
||
/** | ||
|
@@ -59,6 +64,8 @@ public class InAppMessageStreamManager { | |
private final AnalyticsEventsManager analyticsEventsManager; | ||
private final TestDeviceHelper testDeviceHelper; | ||
private final AbtIntegrationHelper abtIntegrationHelper; | ||
private final FirebaseInstanceId firebaseInstanceId; | ||
private final DataCollectionHelper dataCollectionHelper; | ||
|
||
@Inject | ||
public InAppMessageStreamManager( | ||
|
@@ -73,6 +80,8 @@ public InAppMessageStreamManager( | |
RateLimiterClient rateLimiterClient, | ||
@AppForeground RateLimit appForegroundRateLimit, | ||
TestDeviceHelper testDeviceHelper, | ||
FirebaseInstanceId firebaseInstanceId, | ||
DataCollectionHelper dataCollectionHelper, | ||
AbtIntegrationHelper abtIntegrationHelper) { | ||
this.appForegroundEventFlowable = appForegroundEventFlowable; | ||
this.programmaticTriggerEventFlowable = programmaticTriggerEventFlowable; | ||
|
@@ -85,6 +94,8 @@ public InAppMessageStreamManager( | |
this.rateLimiterClient = rateLimiterClient; | ||
this.appForegroundRateLimit = appForegroundRateLimit; | ||
this.testDeviceHelper = testDeviceHelper; | ||
this.dataCollectionHelper = dataCollectionHelper; | ||
this.firebaseInstanceId = firebaseInstanceId; | ||
this.abtIntegrationHelper = abtIntegrationHelper; | ||
} | ||
|
||
|
@@ -232,22 +243,35 @@ public Flowable<TriggeredInAppMessage> createFirebaseInAppMessageStream() { | |
.defaultIfEmpty(CampaignImpressionList.getDefaultInstance()) | ||
.onErrorResumeNext(Maybe.just(CampaignImpressionList.getDefaultInstance())); | ||
|
||
Maybe<InstanceIdResult> getIID = taskToMaybe(firebaseInstanceId.getInstanceId()); | ||
JasonAHeron marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Function<CampaignImpressionList, Maybe<FetchEligibleCampaignsResponse>> serviceFetch = | ||
impressions -> | ||
taskToMaybe(apiClient.getFiams(impressions)) | ||
.doOnSuccess( | ||
resp -> | ||
Logging.logi( | ||
String.format( | ||
Locale.US, | ||
"Successfully fetched %d messages from backend", | ||
resp.getMessagesList().size()))) | ||
.doOnSuccess( | ||
resp -> impressionStorageClient.clearImpressions(resp).subscribe()) | ||
.doOnSuccess(analyticsEventsManager::updateContextualTriggers) | ||
.doOnSuccess(testDeviceHelper::processCampaignFetch) | ||
.doOnError(e -> Logging.logw("Service fetch error: " + e.getMessage())) | ||
.onErrorResumeNext(Maybe.empty()); // Absorb service failures | ||
campaignImpressionList -> { | ||
if (!dataCollectionHelper.isAutomaticDataCollectionEnabled()) { | ||
Logging.logi( | ||
"Automatic data collection is disabled, not attempting campaign fetch from service."); | ||
return Maybe.just(cacheExpiringResponse()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking out loud: Can this be modelled as an empty as well, similar to IID? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm maybe but I think this is pretty clear There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. like it could map to empty or something like that but I think it's not worth it |
||
} | ||
|
||
// blocking get occurs on the IO thread because that's what we observeOn above | ||
return Maybe.fromCallable(getIID::blockingGet) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should be able to just return getIID here, which is already a Maybe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah but I need to do blocking get which turns it into a not maybe, if I don't do blocking get here the waiting ends up hitting the main thread below |
||
.filter(InAppMessageStreamManager::validIID) | ||
.map(iid -> apiClient.getFiams(iid, campaignImpressionList)) | ||
.switchIfEmpty(Maybe.just(cacheExpiringResponse())) | ||
.doOnSuccess( | ||
resp -> | ||
Logging.logi( | ||
String.format( | ||
Locale.US, | ||
"Successfully fetched %d messages from backend", | ||
resp.getMessagesList().size()))) | ||
.doOnSuccess( | ||
resp -> impressionStorageClient.clearImpressions(resp).subscribe()) | ||
.doOnSuccess(analyticsEventsManager::updateContextualTriggers) | ||
.doOnSuccess(testDeviceHelper::processCampaignFetch) | ||
.doOnError(e -> Logging.logw("Service fetch error: " + e.getMessage())) | ||
.onErrorResumeNext(Maybe.empty()); // Absorb service failures | ||
}; | ||
|
||
if (shouldIgnoreCache(event)) { | ||
Logging.logi( | ||
|
@@ -349,6 +373,17 @@ private Maybe<TriggeredInAppMessage> triggeredInAppMessage(ThickContent content, | |
return Maybe.just(new TriggeredInAppMessage(inAppMessage, event)); | ||
} | ||
|
||
private static boolean validIID(@Nullable InstanceIdResult iid) { | ||
return iid != null && !TextUtils.isEmpty(iid.getId()) && !TextUtils.isEmpty(iid.getToken()); | ||
} | ||
|
||
@VisibleForTesting | ||
static FetchEligibleCampaignsResponse cacheExpiringResponse() { | ||
// Within the cache, we use '0' as a special case to 'never' expire. '1' is used when we want to | ||
// retry the getFiams call on subsequent event triggers, and force the cache to always expire | ||
return FetchEligibleCampaignsResponse.newBuilder().setExpirationEpochTimestampMillis(1).build(); | ||
} | ||
|
||
private static <T> Maybe<T> taskToMaybe(Task<T> task) { | ||
return Maybe.create( | ||
emitter -> { | ||
|
Uh oh!
There was an error while loading. Please reload this page.