Skip to content

Bug 2040784 - Introduce AIFeatureState to handle the "Unknown" states of AI controls - #273

Closed
segunfamisa wants to merge 1 commit into
mozilla-firefox:autolandfrom
segunfamisa:ai/cfr-controls
Closed

Bug 2040784 - Introduce AIFeatureState to handle the "Unknown" states of AI controls#273
segunfamisa wants to merge 1 commit into
mozilla-firefox:autolandfrom
segunfamisa:ai/cfr-controls

Conversation

@segunfamisa

Copy link
Copy Markdown
Contributor

This fixes the issue in bug 2040784 by ensuring that we have an unknown state where we don't know yet if the feature is enabled or not. This becomes important when we need to know if the user turned a feature on explicitly, or it was on by default, or they just never never interacted with the feature.

… of AI controls

This fixes the issue in bug 2040784 by ensuring that we have an unknown state where we don't know yet if the feature is enabled or not.
This becomes important when we need to know if the user turned a feature on explicitly, or it was on by default, or they just never never interacted with the feature.
@segunfamisa

Copy link
Copy Markdown
Contributor Author

@github-actions

Copy link
Copy Markdown
Contributor

View this pull request in Lando to land it once approved.

@lando-web
lando-web Bot requested a review from a team May 29, 2026 15:49

@MatthewTighe MatthewTighe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

few small things, but this otherwise LGTM. thanks for taking this one

Comment on lines +21 to +24
context: Context,
): AIFeatureRegistry =
DefaultAIFeatureRegistry(scope, AIFeatureBlockStorage.dataStore(context))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we swap the context dependency for an AIFeatureBlockStorage dependency?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah, I see why this was chosen now - we didn't want to expose the internal type. Carry on

assertFalse(block.isBlocked.first())
}

private class FakeAIFeatureRegistry : AIFeatureRegistry {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we could just reuse AIFeatureRegistry.inMemory for this

Comment on lines +97 to +106
private class TestAIFeatureBlockStorage(initialBlocked: Boolean) : AIFeatureBlockStorage {
val blockedFlow = MutableStateFlow(initialBlocked)
override val isBlocked: Flow<Boolean> = blockedFlow

override suspend fun setBlocked(isBlocked: Boolean) {
blockedFlow.value = isBlocked
}
}

private class TestAIControllableFeature(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These could also use the .inMemory factories I believe

Comment on lines +41 to +47
scope.launch {
if (feature.featureState.first() is AIFeatureState.Unknown) {
val aiFeaturesBlocked = storage.isBlocked.first()
feature.set(!aiFeaturesBlocked)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should move to the IO dispatcher here since we are using the MainScope

@segunfamisa segunfamisa closed this Jun 9, 2026
@segunfamisa
segunfamisa deleted the ai/cfr-controls branch June 18, 2026 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants