// Nothing Gradle builds here may land on another checkout's emulator. // // Android's install, uninstall and connected-test tasks talk to the adb // server directly and act on *every* attached device -- the wrapper `adb` in // this repo never sees them, so none of its aiming applies. With two // sessions' emulators up, `./gradlew installDebug` replaces the app on both, // reports success, and says nothing; from the other session that reads as // its own build never landing. It happened on 2026-08-31. // // This is an init script, applied to every build on this machine, rather // than something each project opts into: a rule a checkout has to adopt is // one the next checkout will not have, and the sessions this protects are // working in checkouts nobody has visited yet. // // The decision itself is `emu check` (one rule for "which device does a // command here mean", shared with the adb wrapper), run in the project's own // directory because that is what names the AVD. It refuses only when another // checkout's emulator is attached; EMU_ANY_DEVICE=1 means every device // anyway. def emu = new File(System.getProperty("user.home"), ".local/bin/emu").absolutePath gradle.allprojects { project -> def workingDir = project.rootDir project.tasks.configureEach { task -> // Matched on where the task class comes from as well as on its name: // a build of any kind may have an `install`, and this must not fail // a project that has nothing to do with a device. if (!task.getClass().name.startsWith('com.android.')) return if (!(task.name =~ /^(install|uninstall|connected)/)) return task.doFirst { def said def status try { def process = new ProcessBuilder(emu, 'check') .directory(workingDir) .redirectErrorStream(true) .start() said = process.inputStream.getText('UTF-8') status = process.waitFor() } catch (IOException e) { // Failing closed: this script is installed by // emulator-tools, so `emu` missing means a half-installation // rather than a machine that never had the guard. throw new org.gradle.api.GradleException( "\ncannot check which emulator this build means: ${emu} is not runnable" + "\n run ~/repos/emulator-tools/install.sh, or set EMU_ANY_DEVICE=1") } if (status != 0) { throw new org.gradle.api.GradleException('\n' + said.trim()) } } } }