Skip to content
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

Runtime-Configurable Engine Options (Similar to FieldTrial / RemoteConfig) #160902

Closed
bc-lee opened this issue Dec 27, 2024 · 3 comments · May be fixed by flutter/website#11568
Closed

Runtime-Configurable Engine Options (Similar to FieldTrial / RemoteConfig) #160902

bc-lee opened this issue Dec 27, 2024 · 3 comments · May be fixed by flutter/website#11568
Labels
r: solved Issue is closed as solved

Comments

@bc-lee
Copy link

bc-lee commented Dec 27, 2024

Use case

From what I understand, the Flutter engine currently lacks runtime-configurable options, leaving developers with little flexibility once the engine is initialized. While this works for many use cases, recent developments—such as the introduction of Impeller on Android—have exposed significant issues on specific devices. The diversity of Android hardware and inconsistent Vulkan driver quality further complicate the situation.

Flutter provides limited build-time customization (e.g., <meta-data> in the Android manifest to enable or disable Impeller). However, changing these settings requires a full rebuild and re-deployment. This process is not only time-consuming—especially on iOS, where app review delays are common—but also reduces stakeholders’ confidence in Flutter’s readiness for production environments.

Proposal

Introduce runtime-configurable engine options to provide developers with greater flexibility in managing critical settings. For example, developers could dynamically switch between the legacy Skia renderer and Impeller without requiring a rebuild. If implementing separate controls for each option proves challenging, consider adopting Chromium’s approach using runtime-configurable features or field trials (e.g., Flutter-Use-Impeller/Disabled/). This system enables defining and adjusting options in a centralized, declarative format at runtime.

By enabling runtime-configurable engine options, Flutter developers could:

  • Gradually roll out new features: Test features like Impeller with a subset of users to ensure compatibility before a full release.
  • Revert to stable configurations: Quickly disable problematic features if critical issues arise in production.
  • Enhance stability and reliability: Improve developer confidence and reduce risks associated with device-specific issues.
  • Streamline development workflows: Avoid lengthy rebuilds and redeployments, saving time and effort.

This change would significantly enhance Flutter’s appeal as a production-ready framework by addressing one of the most critical pain points for developers working in diverse hardware environments.

@iapicca
Copy link
Contributor

iapicca commented Dec 28, 2024

it doesn't seem possible, see comment below

@darshankawar darshankawar added the in triage Presently being triaged by the triage team label Jan 3, 2025
@darshankawar
Copy link
Member

@bc-lee
Please check above to see if it helps in your case or not.

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jan 3, 2025
@bc-lee
Copy link
Author

bc-lee commented Jan 3, 2025

Apologies for posting prematurely before fully investigating the issue. After further digging, I managed to dynamically control the use of Impeller at runtime, particularly with Firebase Remote Config. Here's the code snippet I used for testing. (Tested in Flutter 3.27.1) I'll be closing this issue now.

package com.example.sampleapp

import android.os.Bundle
import android.util.Log
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfigSettings
import com.google.firebase.ktx.Firebase
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterShellArgs

class MainActivity : FlutterActivity() {

    private lateinit var remoteConfig: FirebaseRemoteConfig

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        remoteConfig = Firebase.remoteConfig
        val configSettings = remoteConfigSettings {
            minimumFetchIntervalInSeconds = 3600
        }

        remoteConfig.setConfigSettingsAsync(configSettings).addOnCompleteListener { task ->
            if (task.isSuccessful) {
                remoteConfig.fetchAndActivate().addOnCompleteListener { fetchTask ->
                    if (!fetchTask.isSuccessful) {
                        Log.e(TAG, "Failed to fetch and activate remote config")
                    } else {
                        Log.d(TAG, "Remote config fetched and activated")
                    }
                }
            } else {
                Log.e(TAG, "Failed to set config settings")
            }
        }
    }

    override fun getFlutterShellArgs(): FlutterShellArgs {
        val args = mutableListOf<String>()

        val useImpeller = try {
            // AndroidUseImpeller is a Remote Config parameter that can be used to enable or disable Impeller.
            remoteConfig.getBoolean("AndroidUseImpeller")
        } catch (e: Exception) {
            false
        }

        if (useImpeller) {
            args.add(FlutterShellArgs.ARG_ENABLE_IMPELLER)
        } else {
            args.add(FlutterShellArgs.ARG_DISABLE_IMPELLER)
        }

        return FlutterShellArgs(args)
    }

    companion object {
        private const val TAG = "MainActivity"
    }
}

@bc-lee bc-lee closed this as completed Jan 3, 2025
@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jan 3, 2025
@darshankawar darshankawar added r: solved Issue is closed as solved and removed in triage Presently being triaged by the triage team labels Jan 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
r: solved Issue is closed as solved
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants