Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
f079aca
Release v2.
ychescale9 Dec 7, 2019
da41ec9
Merge branch 'master' into release/v2
ychescale9 Dec 13, 2019
3f52989
Merge branch 'master' into release/v2
ychescale9 Dec 14, 2019
d27f7ec
Merge branch 'master' into release/v2
ychescale9 Jan 19, 2020
5dd12aa
Merge branch 'master' into release/v2
ychescale9 Jan 31, 2020
bdf1f83
Merge branch 'master' into release/v2
ychescale9 Feb 4, 2020
2754675
Merge branch 'master' into release/v2
ychescale9 Feb 15, 2020
6bb3965
Merge branch 'master' into release/v2
ychescale9 Mar 5, 2020
769ff28
Merge branch 'master' into release/v2
ychescale9 Mar 28, 2020
0159db6
Merge branch 'master' into release/v2
ychescale9 Mar 31, 2020
a3b0e6d
Update node_modules.
ychescale9 Mar 31, 2020
e4eb880
Merge branch 'master' into release/v2
ychescale9 Apr 2, 2020
2f678a7
Merge branch 'master' into release/v2
ychescale9 Apr 11, 2020
4f4106d
Merge branch 'master' into release/v2
ychescale9 May 1, 2020
e93c997
Merge branch 'master' into release/v2
ychescale9 May 29, 2020
b62c970
Merge branch 'master' into release/v2
ychescale9 Jun 12, 2020
4a8a9af
Merge branch 'main' into release/v2
ychescale9 Jun 20, 2020
c56210b
Merge branch 'main' into release/v2
ychescale9 Oct 8, 2020
07b0366
Merge branch 'main' into release/v2
ychescale9 Oct 16, 2020
e08f702
Merge branch 'main' into release/v2
ychescale9 Nov 14, 2020
02cf805
Merge branch 'main' into release/v2
ychescale9 Dec 27, 2020
70e3f6e
Merge branch 'main' into release/v2
ychescale9 Dec 28, 2020
94bd1ed
Merge branch 'main' into release/v2
ychescale9 Jan 5, 2021
08b092e
Merge branch 'main' into release/v2
ychescale9 Jan 13, 2021
d279995
Merge branch 'main' into release/v2
ychescale9 Mar 4, 2021
599839e
Merge branch 'main' into release/v2
ychescale9 May 7, 2021
226f262
Merge branch 'main' into release/v2
ychescale9 May 28, 2021
97449e9
Merge branch 'main' into release/v2
ychescale9 Jun 20, 2021
6e775ef
Merge branch 'main' into release/v2
ychescale9 Jun 25, 2021
ac874f3
Merge branch 'main' into release/v2
ychescale9 Jun 26, 2021
5de26e4
Merge branch 'main' into release/v2
ychescale9 Jul 20, 2021
f71c6d1
Merge branch 'main' into release/v2
ychescale9 Aug 28, 2021
2b2ebf2
Merge branch 'main' into release/v2
ychescale9 Oct 23, 2021
48744f2
Merge branch 'main' into release/v2
ychescale9 Dec 24, 2021
76c2bf6
Merge branch 'main' into release/v2
ychescale9 Feb 17, 2022
e790971
Merge branch 'main' into release/v2
ychescale9 Apr 30, 2022
b390b0e
Merge branch 'main' into release/v2
ychescale9 Jul 12, 2022
d7b53dd
Merge branch 'main' into release/v2
ychescale9 Sep 20, 2022
50986b1
Merge branch 'main' into release/v2
ychescale9 Oct 28, 2022
8e947e5
Support non-integer API level (#317)
yujincheng08 Feb 9, 2023
bdaf049
Add renovate.json (#320)
renovate[bot] Feb 18, 2023
bad4154
Update dependency androidx.appcompat:appcompat to v1.6.1 (#322)
renovate[bot] Feb 18, 2023
743ec40
Add emulator-boot-timeout parameter (#326)
koplyarov Mar 9, 2023
8c71f5e
SDK command-line tools 9.0. (#331)
ychescale9 Mar 18, 2023
a2c97ef
Update `test-fixture` dependencies and workflows (#332)
ychescale9 Mar 18, 2023
acd15a6
Cleanup action description.
ychescale9 Mar 18, 2023
b35b1c6
Prepare for release 2.28.0.
ychescale9 Mar 18, 2023
d94c3fb
Merge branch 'main' into release/v2
ychescale9 Mar 18, 2023
e1bdfef
Update README.md (Who is using…) (#335)
rfc2822 Apr 25, 2023
2cfd145
Fixed emulator download URL (#343)
olegdolgikh Jul 4, 2023
fabc291
Upgrade to latest npm dependencies (#347)
yogurtearl Aug 24, 2023
f72f505
Update test fixture dependencies. (#354)
ychescale9 Dec 6, 2023
5a481d2
Check in updated `*.js` file.
ychescale9 Dec 6, 2023
1036f55
Update npm packages. (#355)
ychescale9 Dec 6, 2023
f9c2835
SDK command-line tools 11.0. (#356)
ychescale9 Dec 6, 2023
677db68
Prepare for release 2.29.0.
ychescale9 Dec 6, 2023
99a4aac
Merge branch 'main' into release/v2
ychescale9 Dec 6, 2023
c479bb6
Promote using ubuntu runner with KVM. (#366)
ychescale9 Jan 19, 2024
1e33853
Add another user: robolectric/robolectric (#352)
utzcoz Jan 20, 2024
e1bd48c
Node 20. (#369)
ychescale9 Jan 25, 2024
426fbd2
Prepare for release 2.30.0.
ychescale9 Jan 25, 2024
eaf4c24
Merge branch 'main' into release/v2
ychescale9 Jan 25, 2024
61a61f9
Run the action on Node 20 (#371)
TWiStErRob Jan 26, 2024
bc2cd2a
Prepare for release 2.30.1.
ychescale9 Jan 26, 2024
6b0df4b
Merge branch 'main' into release/v2
ychescale9 Jan 26, 2024
9d5d623
Migrate to Node 20 on CI via GitHub Actions major upgrades (#372)
TWiStErRob Jan 27, 2024
a0c0e72
Bump Gradle wrapper validation from v1 to v2 to use Node 20 (#374)
TWiStErRob Jan 29, 2024
d8da5b6
Add api level `VanillaIceCream` support (#378)
yujincheng08 Feb 17, 2024
1fef06a
Install platforms for the specified api level (#384)
joshrlesch Mar 27, 2024
ca77a10
Prepare for release 2.31.0.
ychescale9 May 24, 2024
77986be
Merge branch 'main' into release/v2
ychescale9 May 24, 2024
4b0628e
Support customizing emulator port (#383)
KamilKurde Jul 2, 2024
e93b947
Add missing compiled js files from #383.
ychescale9 Jul 9, 2024
81f860b
Prepare for release 2.32.0.
ychescale9 Jul 9, 2024
f0d1ed2
Merge branch 'main' into release/v2
ychescale9 Jul 9, 2024
a3dcdb3
Update npm packages. (#401)
ychescale9 Jul 9, 2024
1b985f4
Avoid changing the owner of unnecessary files (#406)
jzbrooks Oct 5, 2024
3a18f50
SDK build tools 35.0.0, command-line tools 16.0. (#408)
ychescale9 Oct 6, 2024
8c07710
Fix SDK path issues with ubuntu-24.04 (#409)
ychescale9 Oct 11, 2024
e800fff
Revert creating avd directory. (#414)
ychescale9 Oct 11, 2024
ead704c
Fix avd path on ubuntu-24.04 - attempt 2 (#415)
ychescale9 Oct 12, 2024
c77bfe7
Prepare for release 2.33.0.
ychescale9 Oct 12, 2024
62dbb60
Merge branch 'main' into release/v2
ychescale9 Oct 12, 2024
50d5b10
Add `Baklava` support (#424)
yujincheng08 Jan 24, 2025
a173d65
Support API levels for SDK extensions and add missing targets for aut…
TimoPtr Mar 28, 2025
595a456
Update README.md and CHANGELOG.md.
ychescale9 Mar 28, 2025
2548f9f
Prepare for release 2.34.0.
ychescale9 Mar 28, 2025
1dcd009
Merge branch 'main' into release/v2
ychescale9 Mar 28, 2025
5302c0e
Fix emulator port issue by removing explicit port assignment
katie-managexr Oct 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Support customizing emulator port (ReactiveCircus#383)
* Add port parameter

* Fix a typo in test description

* Fix avd not being started with correct port

* Fix wrong port being used to kill an emulator if there was an exception
  • Loading branch information
KamilKurde authored Jul 2, 2024
commit 4b0628e9f8ac0c2ac88585f9a0d5bdb21aca470c
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ jobs:
| `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. |
| `force-avd-creation` | Optional | `true` | Whether to force create the AVD by overwriting an existing AVD with the same name as `avd-name` - `true` or `false`. |
| `emulator-boot-timeout` | Optional | `600` | Emulator boot timeout in seconds. If it takes longer to boot, the action would fail - e.g. `300` for 5 minutes. |
| `emulator-port` | Optional | `5554` | Emulator port to use. Allows to run this action on multiple workers on a single machine at the same time. This input is available for the script as `EMULATOR_PORT` enviromental variable. This port is automatically used by android device related tasks in gradle |
| `emulator-options` | Optional | See below | Command-line options used when launching the emulator (replacing all default options) - e.g. `-no-window -no-snapshot -camera-back emulated`. |
| `disable-animations` | Optional | `true` | Whether to disable animations - `true` or `false`. |
| `disable-spellchecker` | Optional | `false` | Whether to disable spellchecker - `true` or `false`. |
Expand Down
28 changes: 28 additions & 0 deletions __tests__/input-validator.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as validator from '../src/input-validator';
import { MAX_PORT, MIN_PORT } from '../src/input-validator';

describe('api-level validator tests', () => {
it('Throws if api-level is not a number', () => {
Expand Down Expand Up @@ -172,6 +173,33 @@ describe('force-avd-creation validator tests', () => {
});
});

describe('emulator-port validator tests', () => {
it('Validates if emulator-port is even and in range', () => {
const func = () => {
validator.checkPort(5554);
};
expect(func).not.toThrow();
});
it('Throws if emulator-port is lower than MIN_PORT', () => {
const func = () => {
validator.checkPort(MIN_PORT - 2);
};
expect(func).toThrow();
});
it('Throws if emulator-port is higher than MAX_PORT', () => {
const func = () => {
validator.checkPort(MAX_PORT + 2);
};
expect(func).toThrow();
});
it('Throws if emulator-port is odd', () => {
const func = () => {
validator.checkPort(5555);
};
expect(func).toThrow();
});
});

describe('disable-animations validator tests', () => {
it('Throws if disable-animations is not a boolean', () => {
const func = () => {
Expand Down
2 changes: 2 additions & 0 deletions action-types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ inputs:
type: boolean
emulator-boot-timeout:
type: integer
emulator-port:
type: integer
emulator-options:
type: string
disable-animations:
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ inputs:
emulator-boot-timeout:
description: 'Emulator boot timeout in seconds. If it takes longer to boot, the action would fail - e.g. `300` for 5 minutes'
default: '600'
emulator-port:
description: 'Port to run emulator on, allows to run multiple emulators on the same physical machine'
default: '5554'
emulator-options:
description: 'command-line options used when launching the emulator - e.g. `-no-window -no-snapshot -camera-back emulated`'
default: '-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim'
Expand Down
29 changes: 17 additions & 12 deletions lib/emulator-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const fs = __importStar(require("fs"));
/**
* Creates and launches a new AVD instance with the specified configurations.
*/
function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, emulatorOptions, disableAnimations, disableSpellChecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard) {
function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, port, emulatorOptions, disableAnimations, disableSpellChecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard) {
return __awaiter(this, void 0, void 0, function* () {
try {
console.log(`::group::Launch Emulator`);
Expand Down Expand Up @@ -82,19 +82,19 @@ function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSiz
},
});
// wait for emulator to complete booting
yield waitForDevice(emulatorBootTimeout);
yield exec.exec(`adb shell input keyevent 82`);
yield waitForDevice(port, emulatorBootTimeout);
yield adb(port, `shell input keyevent 82`);
if (disableAnimations) {
console.log('Disabling animations.');
yield exec.exec(`adb shell settings put global window_animation_scale 0.0`);
yield exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
yield exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
yield adb(port, `shell settings put global window_animation_scale 0.0`);
yield adb(port, `shell settings put global transition_animation_scale 0.0`);
yield adb(port, `shell settings put global animator_duration_scale 0.0`);
}
if (disableSpellChecker) {
yield exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
yield adb(port, `shell settings put secure spell_checker_enabled 0`);
}
if (enableHardwareKeyboard) {
yield exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`);
yield adb(port, `shell settings put secure show_ime_with_hard_keyboard 0`);
}
}
finally {
Expand All @@ -106,11 +106,11 @@ exports.launchEmulator = launchEmulator;
/**
* Kills the running emulator on the default port.
*/
function killEmulator() {
function killEmulator(port) {
return __awaiter(this, void 0, void 0, function* () {
try {
console.log(`::group::Terminate Emulator`);
yield exec.exec(`adb -s emulator-5554 emu kill`);
yield adb(port, `emu kill`);
}
catch (error) {
console.log(error instanceof Error ? error.message : error);
Expand All @@ -121,10 +121,15 @@ function killEmulator() {
});
}
exports.killEmulator = killEmulator;
function adb(port, command) {
return __awaiter(this, void 0, void 0, function* () {
return yield exec.exec(`adb -s emulator-${port} ${command}`);
});
}
/**
* Wait for emulator to boot.
*/
function waitForDevice(emulatorBootTimeout) {
function waitForDevice(port, emulatorBootTimeout) {
return __awaiter(this, void 0, void 0, function* () {
let booted = false;
let attempts = 0;
Expand All @@ -133,7 +138,7 @@ function waitForDevice(emulatorBootTimeout) {
while (!booted) {
try {
let result = '';
yield exec.exec(`adb shell getprop sys.boot_completed`, [], {
yield exec.exec(`adb -s emulator-${port} shell getprop sys.boot_completed`, [], {
listeners: {
stdout: (data) => {
result += data.toString();
Expand Down
13 changes: 12 additions & 1 deletion lib/input-validator.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkDiskSize = exports.checkEmulatorBuild = exports.checkEnableHardwareKeyboard = exports.checkDisableLinuxHardwareAcceleration = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkForceAvdCreation = exports.checkChannel = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.PREVIEW_API_LEVELS = exports.VALID_CHANNELS = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
exports.checkDiskSize = exports.checkEmulatorBuild = exports.checkEnableHardwareKeyboard = exports.checkDisableLinuxHardwareAcceleration = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkPort = exports.checkForceAvdCreation = exports.checkChannel = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.PREVIEW_API_LEVELS = exports.MAX_PORT = exports.MIN_PORT = exports.VALID_CHANNELS = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
exports.MIN_API_LEVEL = 15;
exports.VALID_TARGETS = ['default', 'google_apis', 'aosp_atd', 'google_atd', 'google_apis_playstore', 'android-wear', 'android-wear-cn', 'android-tv', 'google-tv'];
exports.VALID_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
exports.VALID_CHANNELS = ['stable', 'beta', 'dev', 'canary'];
exports.MIN_PORT = 5554;
exports.MAX_PORT = 5584;
exports.PREVIEW_API_LEVELS = ['Tiramisu', 'UpsideDownCake', 'VanillaIceCream'];
function checkApiLevel(apiLevel) {
if (exports.PREVIEW_API_LEVELS.some((previewLevel) => apiLevel.startsWith(previewLevel)))
Expand Down Expand Up @@ -41,6 +43,15 @@ function checkForceAvdCreation(forceAvdCreation) {
}
}
exports.checkForceAvdCreation = checkForceAvdCreation;
function checkPort(port) {
if (port < exports.MIN_PORT || port > exports.MAX_PORT) {
throw new Error(`Emulator port is outside of the supported port range [${exports.MIN_PORT}, ${exports.MAX_PORT}], was ${port}`);
}
if (port % 2 == 1) {
throw new Error(`Emulator port has to be even, was ${port}`);
}
}
exports.checkPort = checkPort;
function checkDisableAnimations(disableAnimations) {
if (!isValidBoolean(disableAnimations)) {
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
Expand Down
14 changes: 10 additions & 4 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ function run() {
// Emulator boot timeout seconds
const emulatorBootTimeout = parseInt(core.getInput('emulator-boot-timeout'), 10);
console.log(`Emulator boot timeout: ${emulatorBootTimeout}`);
// Emulator port to use
const port = parseInt(core.getInput('emulator-port'), 10);
(0, input_validator_1.checkPort)(port);
console.log(`emulator port: ${port}`);
// emulator options
const emulatorOptions = core.getInput('emulator-options').trim();
console.log(`emulator options: ${emulatorOptions}`);
Expand Down Expand Up @@ -193,7 +197,7 @@ function run() {
console.log(`::endgroup::`);
}
// launch an emulator
yield (0, emulator_manager_1.launchEmulator)(apiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, emulatorOptions, disableAnimations, disableSpellchecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard);
yield (0, emulator_manager_1.launchEmulator)(apiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, port, emulatorOptions, disableAnimations, disableSpellchecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard);
// execute the custom script
try {
// move to custom working directory if set
Expand All @@ -203,18 +207,20 @@ function run() {
for (const script of scripts) {
// use array form to avoid various quote escaping problems
// caused by exec(`sh -c "${script}"`)
yield exec.exec('sh', ['-c', script]);
yield exec.exec('sh', ['-c', script], {
env: Object.assign(Object.assign({}, process.env), { EMULATOR_PORT: `${port}`, ANDROID_SERIAL: `emulator-${port}` }),
});
}
}
catch (error) {
core.setFailed(error instanceof Error ? error.message : error);
}
// finally kill the emulator
yield (0, emulator_manager_1.killEmulator)();
yield (0, emulator_manager_1.killEmulator)(port);
}
catch (error) {
// kill the emulator so the action can exit
yield (0, emulator_manager_1.killEmulator)();
yield (0, emulator_manager_1.killEmulator)(input_validator_1.MIN_PORT);
core.setFailed(error instanceof Error ? error.message : error);
}
});
Expand Down
29 changes: 17 additions & 12 deletions src/emulator-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export async function launchEmulator(
avdName: string,
forceAvdCreation: boolean,
emulatorBootTimeout: number,
port: number,
emulatorOptions: string,
disableAnimations: boolean,
disableSpellChecker: boolean,
Expand Down Expand Up @@ -65,7 +66,7 @@ export async function launchEmulator(
// start emulator
console.log('Starting emulator.');

await exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -avd "${avdName}" ${emulatorOptions} &"`, [], {
await exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -port ${port} -avd "${avdName}" ${emulatorOptions} &"`, [], {
listeners: {
stderr: (data: Buffer) => {
if (data.toString().includes('invalid command-line parameter')) {
Expand All @@ -76,20 +77,20 @@ export async function launchEmulator(
});

// wait for emulator to complete booting
await waitForDevice(emulatorBootTimeout);
await exec.exec(`adb shell input keyevent 82`);
await waitForDevice(port, emulatorBootTimeout);
await adb(port, `shell input keyevent 82`);

if (disableAnimations) {
console.log('Disabling animations.');
await exec.exec(`adb shell settings put global window_animation_scale 0.0`);
await exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
await exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
await adb(port, `shell settings put global window_animation_scale 0.0`);
await adb(port, `shell settings put global transition_animation_scale 0.0`);
await adb(port, `shell settings put global animator_duration_scale 0.0`);
}
if (disableSpellChecker) {
await exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
await adb(port, `shell settings put secure spell_checker_enabled 0`);
}
if (enableHardwareKeyboard) {
await exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`);
await adb(port, `shell settings put secure show_ime_with_hard_keyboard 0`);
}
} finally {
console.log(`::endgroup::`);
Expand All @@ -99,29 +100,33 @@ export async function launchEmulator(
/**
* Kills the running emulator on the default port.
*/
export async function killEmulator(): Promise<void> {
export async function killEmulator(port: number): Promise<void> {
try {
console.log(`::group::Terminate Emulator`);
await exec.exec(`adb -s emulator-5554 emu kill`);
await adb(port, `emu kill`);
} catch (error) {
console.log(error instanceof Error ? error.message : error);
} finally {
console.log(`::endgroup::`);
}
}

async function adb(port: number, command: string): Promise<number> {
return await exec.exec(`adb -s emulator-${port} ${command}`);
}

/**
* Wait for emulator to boot.
*/
async function waitForDevice(emulatorBootTimeout: number): Promise<void> {
async function waitForDevice(port: number, emulatorBootTimeout: number): Promise<void> {
let booted = false;
let attempts = 0;
const retryInterval = 2; // retry every 2 seconds
const maxAttempts = emulatorBootTimeout / 2;
while (!booted) {
try {
let result = '';
await exec.exec(`adb shell getprop sys.boot_completed`, [], {
await exec.exec(`adb -s emulator-${port} shell getprop sys.boot_completed`, [], {
listeners: {
stdout: (data: Buffer) => {
result += data.toString();
Expand Down
11 changes: 11 additions & 0 deletions src/input-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export const MIN_API_LEVEL = 15;
export const VALID_TARGETS: Array<string> = ['default', 'google_apis', 'aosp_atd', 'google_atd', 'google_apis_playstore', 'android-wear', 'android-wear-cn', 'android-tv', 'google-tv'];
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64', 'arm64-v8a'];
export const VALID_CHANNELS: Array<string> = ['stable', 'beta', 'dev', 'canary'];
export const MIN_PORT = 5554;
export const MAX_PORT = 5584;
export const PREVIEW_API_LEVELS: Array<string> = ['Tiramisu', 'UpsideDownCake', 'VanillaIceCream'];

export function checkApiLevel(apiLevel: string): void {
Expand Down Expand Up @@ -38,6 +40,15 @@ export function checkForceAvdCreation(forceAvdCreation: string): void {
}
}

export function checkPort(port: number): void {
if (port < MIN_PORT || port > MAX_PORT) {
throw new Error(`Emulator port is outside of the supported port range [${MIN_PORT}, ${MAX_PORT}], was ${port}`);
}
if (port % 2 == 1) {
throw new Error(`Emulator port has to be even, was ${port}`);
}
}

export function checkDisableAnimations(disableAnimations: string): void {
if (!isValidBoolean(disableAnimations)) {
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
Expand Down
17 changes: 14 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
checkChannel,
checkEnableHardwareKeyboard,
checkDiskSize,
checkPort,
MIN_PORT,
} from './input-validator';
import { launchEmulator, killEmulator } from './emulator-manager';
import * as exec from '@actions/exec';
Expand All @@ -20,6 +22,7 @@ import { getChannelId } from './channel-id-mapper';
import { accessSync, constants } from 'fs';

async function run() {
let port: number = MIN_PORT;
try {
console.log(`::group::Configure emulator`);
let linuxSupportKVM = false;
Expand Down Expand Up @@ -93,6 +96,11 @@ async function run() {
const emulatorBootTimeout = parseInt(core.getInput('emulator-boot-timeout'), 10);
console.log(`Emulator boot timeout: ${emulatorBootTimeout}`);

// Emulator port to use
port = parseInt(core.getInput('emulator-port'), 10);
checkPort(port);
console.log(`emulator port: ${port}`);

// emulator options
const emulatorOptions = core.getInput('emulator-options').trim();
console.log(`emulator options: ${emulatorOptions}`);
Expand Down Expand Up @@ -210,6 +218,7 @@ async function run() {
avdName,
forceAvdCreation,
emulatorBootTimeout,
port,
emulatorOptions,
disableAnimations,
disableSpellchecker,
Expand All @@ -226,17 +235,19 @@ async function run() {
for (const script of scripts) {
// use array form to avoid various quote escaping problems
// caused by exec(`sh -c "${script}"`)
await exec.exec('sh', ['-c', script]);
await exec.exec('sh', ['-c', script], {
env: { ...process.env, EMULATOR_PORT: `${port}`, ANDROID_SERIAL: `emulator-${port}` },
});
}
} catch (error) {
core.setFailed(error instanceof Error ? error.message : (error as string));
}

// finally kill the emulator
await killEmulator();
await killEmulator(port);
} catch (error) {
// kill the emulator so the action can exit
await killEmulator();
await killEmulator(port);
core.setFailed(error instanceof Error ? error.message : (error as string));
}
}
Expand Down