-
-
Notifications
You must be signed in to change notification settings - Fork 63
ADFA-4128 (11/11): app + bench — wiring Quick Build into the IDE and the benchmark harness #1723
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
Open
fryanpan
wants to merge
51
commits into
feature/ADFA-4128-qb-10-gradle-plugin
from
feature/ADFA-4128-qb-11-app
Open
Changes from all commits
Commits
Show all changes
51 commits
Select commit
Hold shift + click to select a range
10617dc
ADFA-4128: style: spotless reformat of the build-status layout, no fu…
fryanpan 4f676ea
style: spotless reformat of SaveFileAction.kt, no functional change
fryanpan 06a5c9d
ADFA-4128: qb 11/11 app + bench — wires Quick Build into the IDE and …
fryanpan b2b04d6
ADFA-4128: qb 11 review fixes — install rotation window, flag-off int…
fryanpan 9bd17e6
ADFA-4128: state the daemon-timeout rationale without a benchmark mul…
fryanpan 49761f7
ADFA-4128 (11/11): address CodeRabbit review
fryanpan afbbd92
ADFA-4128: manual-QA script fixes from the 22-test device walk
fryanpan 85db996
ADFA-4128: doc corrections from the PR review sweep
fryanpan 067ec88
ADFA-4128: three small UX fixes found by the manual QA walk
fryanpan c52099e
ADFA-4128: record the v1 blocking decision instead of proposing it
fryanpan 4ab6989
ADFA-4128: qb 12 review fixes - two doc corrections held on the trail…
fryanpan f39a6cd
ADFA-4128: two review fixes - a repeated clobber prompt and a hard-co…
fryanpan 44e3c3a
ADFA-4128: the CoGo reload-crashed notice carries the same text as th…
fryanpan dae9a35
ADFA-4128: resolve ProvisioningFailedUnexpectedly to a user-facing st…
fryanpan 7f090ab
ADFA-4128: reliability-gaps #89 is fixed in-stack, not open
fryanpan cbc3501
ADFA-4128: 0902 review round on the app wiring
fryanpan 6bbef3c
ADFA-4128: stop a re-subscribe re-stomping the bar with the start-fai…
fryanpan 3367c86
ADFA-4128: correct the Koin module's "nothing spawns" claim
fryanpan 77d84ae
ADFA-4128: the status line cannot be read by swiping the sheet up
fryanpan 9c3d7e7
ADFA-4128: style: spotless reformat of QuickBuildStatusBar, no functi…
fryanpan 74672e5
ADFA-4128: delete the requestDowngrade parameter and its plumbing
fryanpan 0671447
ADFA-4128: give DaemonStartFailed the user-facing string it was missing
fryanpan 0587bb9
ADFA-4128: build the Quick Build graph off the main thread
fryanpan 4f5c450
ADFA-4128: pin the failed-start tone to the session's lifetime
fryanpan 1caa3ac
ADFA-4128: size the collapsed sheet header to the status text, not to…
fryanpan a932769
ADFA-4128: give the swipe hint room inside the collapsed sheet
fryanpan 4cb2fb5
ADFA-4128: keep the collapsed sheet at its earlier height
fryanpan e8ac84a
ADFA-4128: request a header layout only when the status height changed
fryanpan 83e7611
ADFA-4128: a manifest save runs generateSources again
fryanpan a69fcaf
ADFA-4128: spell the product "Code on the Go" in the unknown-app dialog
fryanpan 26354f1
ADFA-4128: hand status-line ownership to every writer, the debugger i…
fryanpan f79118d
ADFA-4128: arm the bench standard-build latch only once the build hol…
fryanpan 81cf76f
ADFA-4128: never fire a bench autostart against another project's wor…
fryanpan b469770
ADFA-4128: build the Quick Build graph once, off the main thread, and…
fryanpan 96c5207
ADFA-4128: never wipe the daemon directory under a live compile daemon
fryanpan 4755d0b
ADFA-4128: cover the analytics sink's fallbacks, route and outcome names
fryanpan 585bf23
ADFA-4128: adopt the suspend contracts and surface compile diagnostic…
fryanpan ff58db6
ADFA-4128: lay the collapsed header out inside the window so the swip…
fryanpan 883f71d
ADFA-4128: tidy the stager KDoc and the no-op autostart branch
fryanpan 0bef5ed
ADFA-4128: keep the deferral's own generateSources build out of the h…
fryanpan 4936bda
ADFA-4128: size the header for the status block only while it is the …
fryanpan 28f89c2
ADFA-4128: let an unknown-id consent at tap time cover the id the ins…
fryanpan 41057d1
ADFA-4128: await the clobber confirmations on the tap path
fryanpan 9e5bda4
ADFA-4128: post one Quick Build save event per save operation
fryanpan 68e295e
ADFA-4128: abort a Run whose pre-build save found the editor gone
fryanpan 4065b6c
ADFA-4128: do not count a Quick Build stop tap as a feature use
fryanpan c07a6b4
ADFA-4128: ASCII ellipsis in the truncated Gradle cause
fryanpan b5d0ecd
ADFA-4128: pass the rejection to the repeated-connect debug log
fryanpan 8e028fd
ADFA-4128: carry the reinstalled app's uid on a rebuild success
fryanpan 5dc1044
ADFA-4128: manual QA case for Run during the eager proxy-app build
fryanpan e476d20
ADFA-4128: Run Tasks must not inherit a Run tap's clobber answer
fryanpan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
app/src/androidTest/kotlin/com/itsaky/androidide/QuickBuildFlagOffTest.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| package com.itsaky.androidide | ||
|
|
||
| import androidx.test.core.app.ActivityScenario | ||
| import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
| import androidx.test.platform.app.InstrumentationRegistry | ||
| import com.itsaky.androidide.activities.SplashActivity | ||
| import com.itsaky.androidide.activities.editor.EditorHandlerActivity | ||
| import com.itsaky.androidide.app.configuration.IJdkDistributionProvider | ||
| import com.itsaky.androidide.helper.isExperimentsFlagSet | ||
| import com.itsaky.androidide.helper.setExperimentsFlagForTest | ||
| import com.itsaky.androidide.helper.waitForMainHomeOrEditorUi | ||
| import com.itsaky.androidide.screens.QuickBuildScreen.assertQuickBuildButtonAbsent | ||
| import com.itsaky.androidide.screens.QuickBuildScreen.assertQuickBuildButtonShown | ||
| import com.itsaky.androidide.utils.EditorActivityActions | ||
| import com.kaspersky.kaspresso.testcases.api.testcase.TestCase | ||
| import org.junit.Test | ||
| import org.junit.runner.RunWith | ||
|
|
||
| private const val TOOLBAR_TIMEOUT_MS = 15_000L | ||
|
|
||
| /** | ||
| * The shipping-state gate for Quick Build (ADFA-4128, manual test T13): with no | ||
| * `CodeOnTheGo.exp` flag file on the device, the feature must be invisible. | ||
| * | ||
| * The gate is a single read of [com.itsaky.androidide.utils.FeatureFlags.isExperimentsEnabled] | ||
| * at [EditorActivityActions.register], so this drives that decision directly instead of | ||
| * restarting the process: flip the flag, re-register, rebuild the toolbar, look. That also | ||
| * makes the test honest about what it covers - the registration site, not the process-start | ||
| * caching around it. | ||
| * | ||
| * Both directions run in one test on purpose. An absence assertion alone passes when the | ||
| * accessibility selector rots or the toolbar simply never rendered, so the flag-on step | ||
| * ahead of it is load-bearing, not decoration. | ||
| * | ||
| * Runs after [QuickBuildSmokeTest] in [OrderedTestSuite], which leaves the editor open on a | ||
| * synced project - this test needs a populated editor toolbar and creates no project of its | ||
| * own. | ||
| */ | ||
| @RunWith(AndroidJUnit4::class) | ||
| class QuickBuildFlagOffTest : TestCase() { | ||
| private var hadExperimentsFlag = false | ||
|
|
||
| @Test | ||
| fun test_noExperimentsFlagHidesQuickBuild() = | ||
| before { | ||
| // A dev device may legitimately have experiments enabled; restore whatever | ||
| // state this test found. | ||
| hadExperimentsFlag = isExperimentsFlagSet() | ||
| IJdkDistributionProvider.getInstance().loadDistributions() | ||
| }.after { | ||
| setExperimentsFlagForTest(hadExperimentsFlag) | ||
| // Leave the toolbar matching the restored flag so a later test does not | ||
| // inherit this one's registry. | ||
| runCatching { rebuildEditorToolbar() } | ||
| }.run { | ||
| step("Launch app") { | ||
| ActivityScenario.launch(SplashActivity::class.java) | ||
| waitForMainHomeOrEditorUi(device.uiDevice) | ||
| } | ||
|
|
||
| step("Experiments on: the toolbar carries Quick Build") { | ||
| setExperimentsFlagForTest(true) | ||
| rebuildEditorToolbar() | ||
| assertQuickBuildButtonShown(TOOLBAR_TIMEOUT_MS) | ||
| } | ||
|
|
||
| step("Experiments off: the toolbar drops Quick Build") { | ||
| setExperimentsFlagForTest(false) | ||
| rebuildEditorToolbar() | ||
| assertQuickBuildButtonAbsent(TOOLBAR_TIMEOUT_MS) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Re-runs action registration and repopulates the toolbar, which is what an editor | ||
| * launch does. On the main thread: both touch the actions registry and the toolbar | ||
| * views. | ||
| */ | ||
| private fun rebuildEditorToolbar() { | ||
| val instrumentation = InstrumentationRegistry.getInstrumentation() | ||
| val activity = resumedEditorActivity() | ||
| instrumentation.runOnMainSync { | ||
| EditorActivityActions.register(activity) | ||
| activity.prepareOptionsMenu() | ||
| } | ||
| instrumentation.waitForIdleSync() | ||
| } | ||
|
|
||
| private fun resumedEditorActivity(): EditorHandlerActivity = | ||
| device.activities.getResumed() as? EditorHandlerActivity | ||
| ?: error("Resumed activity is not the editor; this test needs an open project") | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMPORTANT: this stages the ~62 MB Quick Build daemon payload into every variant's assets, release included, with no mention of it anywhere in the PR.
androidComponents.onVariants { variant -> ... }has noselector(), socopy<Variant>QuickBuildDaemonZipandcopy<Variant>QuickBuildRuntimeAarrun for release as well as debug. The zip is the daemon jar plus its entireruntimeClasspath(kotlin-build-tools-impl, the embeddable Kotlin compiler) plus the Compose compiler plugin -quickbuild/daemon/build.gradle.ktsputs it at "~62 MB" in its own size audit - and the feature consuming it is opt-in behindFeatureFlags.isExperimentsEnabled. Every user pays the download and the on-device storage; ADR 0005 exists because this project treats APK size as a first-order constraint.Either gate the two
addGeneratedSourceDirectorycalls the way line 714 already gates a release-only block, or state the measured release-APK delta in the PR body so the release owner can make the call deliberately. I did not build an APK, so the exact delta is unverified.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Measured for the body rather than gated. The zip is a byte copy into
assets/data/common/:quickbuild-daemon.zipis 61,963,732 bytes, the runtime AAR 95,371; both are innoCompressfor release, so the release APK grows by 62.06 MB (59.2 MiB). Gating the copy to debug would break release:FeatureFlags.isExperimentsEnabledis a runtime preference a release user can turn on, and the daemon is what Quick Build runs. Once the flag graduates the payload is the feature's cost either way. The delta and the reasoning are in the PR body for the release owner.