mirror of
https://github.com/reactivecircus/android-emulator-runner.git
synced 2026-09-03 10:59:32 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b530d96654 | |||
| 016d4d097a | |||
| f9bdb6d84e | |||
| b68ca169d6 | |||
| 66283c0319 | |||
| f2bf410054 | |||
| 62e6348453 | |||
| 450c4c9f73 |
+5
-1
@@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
No changes yet.
|
## v2.35.0
|
||||||
|
|
||||||
|
* Optimize config.ini updates and efficiency improvements report (#436).
|
||||||
|
* Fix `pre-emulator-launch-script` (#439).
|
||||||
|
* Allow `google_apis_ps16k` as a valid target (#440).
|
||||||
|
|
||||||
## v2.34.0
|
## v2.34.0
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ This presents a challenge when running emulators on CI especially when running e
|
|||||||
|
|
||||||
## Running hardware accelerated emulators on Linux runners
|
## Running hardware accelerated emulators on Linux runners
|
||||||
|
|
||||||
GitHub's [larger Linux runners support running hardware accelerated emulators](https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/) which is [free for public GitHub repos](https://github.blog/2024-01-17-github-hosted-runners-double-the-power-for-open-source/). It is now recommended to use the **Ubuntu** (`ubuntu-latest`) runners which are 2-3 times faster than the **macOS** ones which are also a lot more expensive. Remember to enable KVM in your workflow before running this action:
|
GitHub's [larger Linux runners support running hardware accelerated emulators](https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/). It is now recommended to use the **Ubuntu** (`ubuntu-latest`) runners which are 2-3 times faster than the **macOS** ones which are also a lot more expensive. Remember to enable KVM in your workflow before running this action:
|
||||||
|
|
||||||
```
|
```
|
||||||
- name: Enable KVM group perms
|
- name: Enable KVM group perms
|
||||||
@@ -90,7 +90,7 @@ jobs:
|
|||||||
api-level: ${{ matrix.api-level }}
|
api-level: ${{ matrix.api-level }}
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
arch: x86_64
|
arch: x86_64
|
||||||
profile: Nexus 6
|
profile: pixel_7_pro
|
||||||
script: ./gradlew connectedCheck
|
script: ./gradlew connectedCheck
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -206,9 +206,9 @@ jobs:
|
|||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
| `api-level` | Required | N/A | API level of the platform and system image - e.g. `23`, `33`, `35-ext15`, `Baklava`. **Minimum API level supported is 15**. |
|
| `api-level` | Required | N/A | API level of the platform and system image - e.g. `23`, `33`, `35-ext15`, `Baklava`. **Minimum API level supported is 15**. |
|
||||||
| `system-image-api-level` | Optional | same as `api-level` | API level of the system image - e.g. `34-ext10`, `35-ext15`. |
|
| `system-image-api-level` | Optional | same as `api-level` | API level of the system image - e.g. `34-ext10`, `35-ext15`. |
|
||||||
| `target` | Optional | `default` | Target of the system image - `default`, `google_apis`, `playstore`, `android-wear`, `android-wear-cn`, `android-tv`, `google-tv`, `aosp_atd`, `google_atd`, `android-automotive`, `android-automotive-playstore` or `android-desktop`. Note that `aosp_atd` and `google_atd` currently require the following: `api-level: 30`, `arch: x86` or `arch: arm64-v8` and `channel: canary`. |
|
| `target` | Optional | `default` | Target of the system image - e.g. `default`, `google_apis`, `google_apis_ps16k`, `google_apis_playstore`, `google_apis_playstore_ps16k`, `android-wear`, `android-wear-cn`, `android-tv`, `google-tv`, `aosp_atd`, `google_atd`, `android-automotive`, `android-automotive-playstore`, `android-desktop`. Please run `sdkmanager --list` to see the available targets. |
|
||||||
| `arch` | Optional | `x86` | CPU architecture of the system image - `x86`, `x86_64` or `arm64-v8a`. Note that `x86_64` image is only available for API 21+. `arm64-v8a` images require Android 4.2+ and are limited to fewer API levels (e.g. 30). |
|
| `arch` | Optional | `x86` | CPU architecture of the system image - `x86`, `x86_64` or `arm64-v8a`. Note that `x86_64` image is only available for API 21+. `arm64-v8a` images require Android 4.2+ and are limited to fewer API levels (e.g. 30). |
|
||||||
| `profile` | Optional | N/A | Hardware profile used for creating the AVD - e.g. `Nexus 6`. For a list of all profiles available, run `avdmanager list device`. |
|
| `profile` | Optional | N/A | Hardware profile id used for creating the AVD - e.g. `pixel_7_pro`. For a list of all profiles available, run `avdmanager list device`. |
|
||||||
| `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). |
|
| `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). |
|
||||||
| `ram-size` | Optional | N/A | Size of RAM to use for this AVD, in KB or MB, denoted with K or M. - e.g. `2048M` |
|
| `ram-size` | Optional | N/A | Size of RAM to use for this AVD, in KB or MB, denoted with K or M. - e.g. `2048M` |
|
||||||
| `heap-size` | Optional | N/A | Heap size to use for this AVD, in KB or MB, denoted with K or M. - e.g. `512M` |
|
| `heap-size` | Optional | N/A | Heap size to use for this AVD, in KB or MB, denoted with K or M. - e.g. `512M` |
|
||||||
|
|||||||
@@ -1,77 +1,6 @@
|
|||||||
import * as validator from '../src/input-validator';
|
import * as validator from '../src/input-validator';
|
||||||
import { MAX_PORT, MIN_PORT } from '../src/input-validator';
|
import { MAX_PORT, MIN_PORT } from '../src/input-validator';
|
||||||
|
|
||||||
describe('target validator tests', () => {
|
|
||||||
it('Throws if target is unknown', () => {
|
|
||||||
const func = () => {
|
|
||||||
validator.checkTarget('some-target');
|
|
||||||
};
|
|
||||||
expect(func).toThrowError(`Value for input.target 'some-target' is unknown. Supported options: ${validator.VALID_TARGETS}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Validates successfully with valid target', () => {
|
|
||||||
const func1 = () => {
|
|
||||||
validator.checkTarget('default');
|
|
||||||
};
|
|
||||||
expect(func1).not.toThrow();
|
|
||||||
|
|
||||||
const func2 = () => {
|
|
||||||
validator.checkTarget('google_apis');
|
|
||||||
};
|
|
||||||
expect(func2).not.toThrow();
|
|
||||||
|
|
||||||
const func3 = () => {
|
|
||||||
validator.checkTarget('aosp_atd');
|
|
||||||
};
|
|
||||||
expect(func3).not.toThrow();
|
|
||||||
|
|
||||||
const func4 = () => {
|
|
||||||
validator.checkTarget('google_atd');
|
|
||||||
};
|
|
||||||
expect(func4).not.toThrow();
|
|
||||||
|
|
||||||
const func5 = () => {
|
|
||||||
validator.checkTarget('google_apis_playstore');
|
|
||||||
};
|
|
||||||
expect(func5).not.toThrow();
|
|
||||||
|
|
||||||
const func6 = () => {
|
|
||||||
validator.checkTarget('android-wear');
|
|
||||||
};
|
|
||||||
expect(func6).not.toThrow();
|
|
||||||
|
|
||||||
const func7 = () => {
|
|
||||||
validator.checkTarget('android-wear-cn');
|
|
||||||
};
|
|
||||||
expect(func7).not.toThrow();
|
|
||||||
|
|
||||||
const func8 = () => {
|
|
||||||
validator.checkTarget('android-tv');
|
|
||||||
};
|
|
||||||
expect(func8).not.toThrow();
|
|
||||||
|
|
||||||
const func9 = () => {
|
|
||||||
validator.checkTarget('google-tv');
|
|
||||||
};
|
|
||||||
expect(func9).not.toThrow();
|
|
||||||
|
|
||||||
const func10 = () => {
|
|
||||||
validator.checkTarget('android-automotive');
|
|
||||||
};
|
|
||||||
expect(func10).not.toThrow();
|
|
||||||
|
|
||||||
const func11 = () => {
|
|
||||||
validator.checkTarget('android-automotive-playstore');
|
|
||||||
};
|
|
||||||
expect(func11).not.toThrow();
|
|
||||||
|
|
||||||
const func12 = () => {
|
|
||||||
validator.checkTarget('android-desktop');
|
|
||||||
};
|
|
||||||
expect(func12).not.toThrow();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('arch validator tests', () => {
|
describe('arch validator tests', () => {
|
||||||
it('Throws if arch is unknown', () => {
|
it('Throws if arch is unknown', () => {
|
||||||
const func = () => {
|
const func = () => {
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ inputs:
|
|||||||
description: 'API level of the system image - e.g. 34-ext10, 35-ext15. If not set the `api-level` input will be used.'
|
description: 'API level of the system image - e.g. 34-ext10, 35-ext15. If not set the `api-level` input will be used.'
|
||||||
required: false
|
required: false
|
||||||
target:
|
target:
|
||||||
description: 'target of the system image - default, google_apis, google_apis_playstore, aosp_atd, google_atd, android-wear, android-wear-cn, android-tv, google-tv, android-automotive, android-automotive-playstore or android-desktop'
|
description: 'target of the system image - e.g. default, google_apis, google_apis_ps16k, google_apis_playstore, google_apis_playstore_16k, aosp_atd, google_atd, android-wear, android-wear-cn, android-tv, google-tv, android-automotive, android-automotive-playstore or android-desktop'
|
||||||
default: 'default'
|
default: 'default'
|
||||||
arch:
|
arch:
|
||||||
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
|
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
|
||||||
|
|||||||
+39
-18
@@ -32,16 +32,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.killEmulator = exports.launchEmulator = void 0;
|
exports.killEmulator = exports.launchEmulator = exports.createAvd = void 0;
|
||||||
const exec = __importStar(require("@actions/exec"));
|
const exec = __importStar(require("@actions/exec"));
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
/**
|
/**
|
||||||
* Creates and launches a new AVD instance with the specified configurations.
|
* Creates a new AVD instance with the specified configurations.
|
||||||
*/
|
*/
|
||||||
function launchEmulator(systemImageApiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, port, emulatorOptions, disableAnimations, disableSpellChecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard) {
|
function createAvd(arch, avdName, cores, diskSize, enableHardwareKeyboard, forceAvdCreation, heapSize, profile, ramSize, sdcardPathOrSize, systemImageApiLevel, target) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
console.log(`::group::Launch Emulator`);
|
console.log(`::group::Create AVD`);
|
||||||
// create a new AVD if AVD directory does not already exist or forceAvdCreation is true
|
// create a new AVD if AVD directory does not already exist or forceAvdCreation is true
|
||||||
const avdPath = `${process.env.ANDROID_AVD_HOME}/${avdName}.avd`;
|
const avdPath = `${process.env.ANDROID_AVD_HOME}/${avdName}.avd`;
|
||||||
if (!fs.existsSync(avdPath) || forceAvdCreation) {
|
if (!fs.existsSync(avdPath) || forceAvdCreation) {
|
||||||
@@ -50,21 +50,42 @@ function launchEmulator(systemImageApiLevel, target, arch, profile, cores, ramSi
|
|||||||
console.log(`Creating AVD.`);
|
console.log(`Creating AVD.`);
|
||||||
yield exec.exec(`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${systemImageApiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`);
|
yield exec.exec(`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${systemImageApiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`);
|
||||||
}
|
}
|
||||||
if (cores) {
|
if (cores || ramSize || heapSize || enableHardwareKeyboard || diskSize) {
|
||||||
yield exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
const configEntries = [];
|
||||||
}
|
if (cores) {
|
||||||
if (ramSize) {
|
configEntries.push(`hw.cpu.ncore=${cores}`);
|
||||||
yield exec.exec(`sh -c \\"printf 'hw.ramSize=${ramSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
}
|
||||||
}
|
if (ramSize) {
|
||||||
if (heapSize) {
|
configEntries.push(`hw.ramSize=${ramSize}`);
|
||||||
yield exec.exec(`sh -c \\"printf 'hw.heapSize=${heapSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
}
|
||||||
}
|
if (heapSize) {
|
||||||
if (enableHardwareKeyboard) {
|
configEntries.push(`hw.heapSize=${heapSize}`);
|
||||||
yield exec.exec(`sh -c \\"printf 'hw.keyboard=yes\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
}
|
||||||
}
|
if (enableHardwareKeyboard) {
|
||||||
if (diskSize) {
|
configEntries.push('hw.keyboard=yes');
|
||||||
yield exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
}
|
||||||
|
if (diskSize) {
|
||||||
|
configEntries.push(`disk.dataPartition.size=${diskSize}`);
|
||||||
|
}
|
||||||
|
if (configEntries.length > 0) {
|
||||||
|
const configContent = configEntries.join('\\n') + '\\n';
|
||||||
|
yield exec.exec(`sh -c \\"printf '${configContent}' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini"`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
console.log(`::endgroup::`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.createAvd = createAvd;
|
||||||
|
/**
|
||||||
|
* Launches an existing AVD instance with the specified configurations.
|
||||||
|
*/
|
||||||
|
function launchEmulator(avdName, disableAnimations, disableLinuxHardwareAcceleration, disableSpellChecker, emulatorBootTimeout, emulatorOptions, enableHardwareKeyboard, port) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
try {
|
||||||
|
console.log(`::group::Launch Emulator`);
|
||||||
// turn off hardware acceleration on Linux
|
// turn off hardware acceleration on Linux
|
||||||
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
||||||
console.log('Disabling Linux hardware acceleration.');
|
console.log('Disabling Linux hardware acceleration.');
|
||||||
|
|||||||
+10
-20
@@ -1,31 +1,21 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.checkDiskSize = exports.checkEmulatorBuild = exports.checkEnableHardwareKeyboard = exports.checkDisableLinuxHardwareAcceleration = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkPort = exports.checkForceAvdCreation = exports.checkChannel = exports.checkArch = exports.checkTarget = exports.MAX_PORT = exports.MIN_PORT = 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.playstoreTargetSubstitution = exports.MAX_PORT = exports.MIN_PORT = exports.VALID_CHANNELS = exports.VALID_ARCHS = exports.MIN_API_LEVEL = void 0;
|
||||||
exports.MIN_API_LEVEL = 15;
|
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',
|
|
||||||
'android-automotive',
|
|
||||||
'android-automotive-playstore',
|
|
||||||
'android-desktop',
|
|
||||||
];
|
|
||||||
exports.VALID_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
|
exports.VALID_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
|
||||||
exports.VALID_CHANNELS = ['stable', 'beta', 'dev', 'canary'];
|
exports.VALID_CHANNELS = ['stable', 'beta', 'dev', 'canary'];
|
||||||
exports.MIN_PORT = 5554;
|
exports.MIN_PORT = 5554;
|
||||||
exports.MAX_PORT = 5584;
|
exports.MAX_PORT = 5584;
|
||||||
function checkTarget(target) {
|
function playstoreTargetSubstitution(target) {
|
||||||
if (!exports.VALID_TARGETS.includes(target)) {
|
// "playstore" is an allowed shorthand for "google_apis_playstore" images
|
||||||
throw new Error(`Value for input.target '${target}' is unknown. Supported options: ${exports.VALID_TARGETS}.`);
|
// this is idempotent - return same even if run multiple times on same target
|
||||||
}
|
if (target === 'playstore')
|
||||||
|
return 'google_apis_playstore';
|
||||||
|
if (target === 'playstore_ps16k')
|
||||||
|
return 'google_apis_playstore_ps16k';
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
exports.checkTarget = checkTarget;
|
exports.playstoreTargetSubstitution = playstoreTargetSubstitution;
|
||||||
function checkArch(arch) {
|
function checkArch(arch) {
|
||||||
if (!exports.VALID_ARCHS.includes(arch)) {
|
if (!exports.VALID_ARCHS.includes(arch)) {
|
||||||
throw new Error(`Value for input.arch '${arch}' is unknown. Supported options: ${exports.VALID_ARCHS}.`);
|
throw new Error(`Value for input.arch '${arch}' is unknown. Supported options: ${exports.VALID_ARCHS}.`);
|
||||||
|
|||||||
+4
-4
@@ -70,9 +70,7 @@ function run() {
|
|||||||
}
|
}
|
||||||
console.log(`System image API level: ${systemImageApiLevel}`);
|
console.log(`System image API level: ${systemImageApiLevel}`);
|
||||||
// target of the system image
|
// target of the system image
|
||||||
const targetInput = core.getInput('target');
|
const target = (0, input_validator_1.playstoreTargetSubstitution)(core.getInput('target'));
|
||||||
const target = targetInput == 'playstore' ? 'google_apis_playstore' : targetInput;
|
|
||||||
(0, input_validator_1.checkTarget)(target);
|
|
||||||
console.log(`target: ${target}`);
|
console.log(`target: ${target}`);
|
||||||
// CPU architecture of the system image
|
// CPU architecture of the system image
|
||||||
const arch = core.getInput('arch');
|
const arch = core.getInput('arch');
|
||||||
@@ -184,6 +182,8 @@ function run() {
|
|||||||
console.log(`::endgroup::`);
|
console.log(`::endgroup::`);
|
||||||
// install SDK
|
// install SDK
|
||||||
yield (0, sdk_installer_1.installAndroidSdk)(apiLevel, systemImageApiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
yield (0, sdk_installer_1.installAndroidSdk)(apiLevel, systemImageApiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
||||||
|
// create AVD
|
||||||
|
yield (0, emulator_manager_1.createAvd)(arch, avdName, cores, diskSize, enableHardwareKeyboard, forceAvdCreation, heapSize, profile, ramSize, sdcardPathOrSize, systemImageApiLevel, target);
|
||||||
// execute pre emulator launch script if set
|
// execute pre emulator launch script if set
|
||||||
if (preEmulatorLaunchScripts !== undefined) {
|
if (preEmulatorLaunchScripts !== undefined) {
|
||||||
console.log(`::group::Run pre emulator launch script`);
|
console.log(`::group::Run pre emulator launch script`);
|
||||||
@@ -202,7 +202,7 @@ function run() {
|
|||||||
console.log(`::endgroup::`);
|
console.log(`::endgroup::`);
|
||||||
}
|
}
|
||||||
// launch an emulator
|
// launch an emulator
|
||||||
yield (0, emulator_manager_1.launchEmulator)(systemImageApiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, port, emulatorOptions, disableAnimations, disableSpellchecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard);
|
yield (0, emulator_manager_1.launchEmulator)(avdName, disableAnimations, disableLinuxHardwareAcceleration, disableSpellchecker, emulatorBootTimeout, emulatorOptions, enableHardwareKeyboard, port);
|
||||||
// execute the custom script
|
// execute the custom script
|
||||||
try {
|
try {
|
||||||
// move to custom working directory if set
|
// move to custom working directory if set
|
||||||
|
|||||||
+52
-33
@@ -2,30 +2,24 @@ import * as exec from '@actions/exec';
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and launches a new AVD instance with the specified configurations.
|
* Creates a new AVD instance with the specified configurations.
|
||||||
*/
|
*/
|
||||||
export async function launchEmulator(
|
export async function createAvd(
|
||||||
systemImageApiLevel: string,
|
|
||||||
target: string,
|
|
||||||
arch: string,
|
arch: string,
|
||||||
profile: string,
|
|
||||||
cores: string,
|
|
||||||
ramSize: string,
|
|
||||||
heapSize: string,
|
|
||||||
sdcardPathOrSize: string,
|
|
||||||
diskSize: string,
|
|
||||||
avdName: string,
|
avdName: string,
|
||||||
|
cores: string,
|
||||||
|
diskSize: string,
|
||||||
|
enableHardwareKeyboard: boolean,
|
||||||
forceAvdCreation: boolean,
|
forceAvdCreation: boolean,
|
||||||
emulatorBootTimeout: number,
|
heapSize: string,
|
||||||
port: number,
|
profile: string,
|
||||||
emulatorOptions: string,
|
ramSize: string,
|
||||||
disableAnimations: boolean,
|
sdcardPathOrSize: string,
|
||||||
disableSpellChecker: boolean,
|
systemImageApiLevel: string,
|
||||||
disableLinuxHardwareAcceleration: boolean,
|
target: string
|
||||||
enableHardwareKeyboard: boolean
|
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
console.log(`::group::Launch Emulator`);
|
console.log(`::group::Create AVD`);
|
||||||
// create a new AVD if AVD directory does not already exist or forceAvdCreation is true
|
// create a new AVD if AVD directory does not already exist or forceAvdCreation is true
|
||||||
const avdPath = `${process.env.ANDROID_AVD_HOME}/${avdName}.avd`;
|
const avdPath = `${process.env.ANDROID_AVD_HOME}/${avdName}.avd`;
|
||||||
if (!fs.existsSync(avdPath) || forceAvdCreation) {
|
if (!fs.existsSync(avdPath) || forceAvdCreation) {
|
||||||
@@ -37,25 +31,50 @@ export async function launchEmulator(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cores) {
|
if (cores || ramSize || heapSize || enableHardwareKeyboard || diskSize) {
|
||||||
await exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
const configEntries: string[] = [];
|
||||||
}
|
|
||||||
|
|
||||||
if (ramSize) {
|
if (cores) {
|
||||||
await exec.exec(`sh -c \\"printf 'hw.ramSize=${ramSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
configEntries.push(`hw.cpu.ncore=${cores}`);
|
||||||
}
|
}
|
||||||
|
if (ramSize) {
|
||||||
|
configEntries.push(`hw.ramSize=${ramSize}`);
|
||||||
|
}
|
||||||
|
if (heapSize) {
|
||||||
|
configEntries.push(`hw.heapSize=${heapSize}`);
|
||||||
|
}
|
||||||
|
if (enableHardwareKeyboard) {
|
||||||
|
configEntries.push('hw.keyboard=yes');
|
||||||
|
}
|
||||||
|
if (diskSize) {
|
||||||
|
configEntries.push(`disk.dataPartition.size=${diskSize}`);
|
||||||
|
}
|
||||||
|
|
||||||
if (heapSize) {
|
if (configEntries.length > 0) {
|
||||||
await exec.exec(`sh -c \\"printf 'hw.heapSize=${heapSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
const configContent = configEntries.join('\\n') + '\\n';
|
||||||
|
await exec.exec(`sh -c \\"printf '${configContent}' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini"`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
console.log(`::endgroup::`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (enableHardwareKeyboard) {
|
/**
|
||||||
await exec.exec(`sh -c \\"printf 'hw.keyboard=yes\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
* Launches an existing AVD instance with the specified configurations.
|
||||||
}
|
*/
|
||||||
|
export async function launchEmulator(
|
||||||
if (diskSize) {
|
avdName: string,
|
||||||
await exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
disableAnimations: boolean,
|
||||||
}
|
disableLinuxHardwareAcceleration: boolean,
|
||||||
|
disableSpellChecker: boolean,
|
||||||
|
emulatorBootTimeout: number,
|
||||||
|
emulatorOptions: string,
|
||||||
|
enableHardwareKeyboard: boolean,
|
||||||
|
port: number
|
||||||
|
): Promise<void> {
|
||||||
|
try {
|
||||||
|
console.log(`::group::Launch Emulator`);
|
||||||
|
|
||||||
// turn off hardware acceleration on Linux
|
// turn off hardware acceleration on Linux
|
||||||
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
||||||
|
|||||||
+6
-18
@@ -1,27 +1,15 @@
|
|||||||
export const MIN_API_LEVEL = 15;
|
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',
|
|
||||||
'android-automotive',
|
|
||||||
'android-automotive-playstore',
|
|
||||||
'android-desktop',
|
|
||||||
];
|
|
||||||
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64', 'arm64-v8a'];
|
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64', 'arm64-v8a'];
|
||||||
export const VALID_CHANNELS: Array<string> = ['stable', 'beta', 'dev', 'canary'];
|
export const VALID_CHANNELS: Array<string> = ['stable', 'beta', 'dev', 'canary'];
|
||||||
export const MIN_PORT = 5554;
|
export const MIN_PORT = 5554;
|
||||||
export const MAX_PORT = 5584;
|
export const MAX_PORT = 5584;
|
||||||
|
|
||||||
export function checkTarget(target: string): void {
|
export function playstoreTargetSubstitution(target: string): string {
|
||||||
if (!VALID_TARGETS.includes(target)) {
|
// "playstore" is an allowed shorthand for "google_apis_playstore" images
|
||||||
throw new Error(`Value for input.target '${target}' is unknown. Supported options: ${VALID_TARGETS}.`);
|
// this is idempotent - return same even if run multiple times on same target
|
||||||
}
|
if (target === 'playstore') return 'google_apis_playstore';
|
||||||
|
if (target === 'playstore_ps16k') return 'google_apis_playstore_ps16k';
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkArch(arch: string): void {
|
export function checkArch(arch: string): void {
|
||||||
|
|||||||
+7
-25
@@ -1,7 +1,6 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import { installAndroidSdk } from './sdk-installer';
|
import { installAndroidSdk } from './sdk-installer';
|
||||||
import {
|
import {
|
||||||
checkTarget,
|
|
||||||
checkArch,
|
checkArch,
|
||||||
checkDisableAnimations,
|
checkDisableAnimations,
|
||||||
checkEmulatorBuild,
|
checkEmulatorBuild,
|
||||||
@@ -12,9 +11,10 @@ import {
|
|||||||
checkEnableHardwareKeyboard,
|
checkEnableHardwareKeyboard,
|
||||||
checkDiskSize,
|
checkDiskSize,
|
||||||
checkPort,
|
checkPort,
|
||||||
|
playstoreTargetSubstitution,
|
||||||
MIN_PORT,
|
MIN_PORT,
|
||||||
} from './input-validator';
|
} from './input-validator';
|
||||||
import { launchEmulator, killEmulator } from './emulator-manager';
|
import { createAvd, launchEmulator, killEmulator } from './emulator-manager';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import { parseScript } from './script-parser';
|
import { parseScript } from './script-parser';
|
||||||
import { getChannelId } from './channel-id-mapper';
|
import { getChannelId } from './channel-id-mapper';
|
||||||
@@ -52,9 +52,7 @@ async function run() {
|
|||||||
console.log(`System image API level: ${systemImageApiLevel}`);
|
console.log(`System image API level: ${systemImageApiLevel}`);
|
||||||
|
|
||||||
// target of the system image
|
// target of the system image
|
||||||
const targetInput = core.getInput('target');
|
const target = playstoreTargetSubstitution(core.getInput('target'));
|
||||||
const target = targetInput == 'playstore' ? 'google_apis_playstore' : targetInput;
|
|
||||||
checkTarget(target);
|
|
||||||
console.log(`target: ${target}`);
|
console.log(`target: ${target}`);
|
||||||
|
|
||||||
// CPU architecture of the system image
|
// CPU architecture of the system image
|
||||||
@@ -191,6 +189,9 @@ async function run() {
|
|||||||
// install SDK
|
// install SDK
|
||||||
await installAndroidSdk(apiLevel, systemImageApiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
await installAndroidSdk(apiLevel, systemImageApiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
||||||
|
|
||||||
|
// create AVD
|
||||||
|
await createAvd(arch, avdName, cores, diskSize, enableHardwareKeyboard, forceAvdCreation, heapSize, profile, ramSize, sdcardPathOrSize, systemImageApiLevel, target);
|
||||||
|
|
||||||
// execute pre emulator launch script if set
|
// execute pre emulator launch script if set
|
||||||
if (preEmulatorLaunchScripts !== undefined) {
|
if (preEmulatorLaunchScripts !== undefined) {
|
||||||
console.log(`::group::Run pre emulator launch script`);
|
console.log(`::group::Run pre emulator launch script`);
|
||||||
@@ -209,26 +210,7 @@ async function run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// launch an emulator
|
// launch an emulator
|
||||||
await launchEmulator(
|
await launchEmulator(avdName, disableAnimations, disableLinuxHardwareAcceleration, disableSpellchecker, emulatorBootTimeout, emulatorOptions, enableHardwareKeyboard, port);
|
||||||
systemImageApiLevel,
|
|
||||||
target,
|
|
||||||
arch,
|
|
||||||
profile,
|
|
||||||
cores,
|
|
||||||
ramSize,
|
|
||||||
heapSize,
|
|
||||||
sdcardPathOrSize,
|
|
||||||
diskSize,
|
|
||||||
avdName,
|
|
||||||
forceAvdCreation,
|
|
||||||
emulatorBootTimeout,
|
|
||||||
port,
|
|
||||||
emulatorOptions,
|
|
||||||
disableAnimations,
|
|
||||||
disableSpellchecker,
|
|
||||||
disableLinuxHardwareAcceleration,
|
|
||||||
enableHardwareKeyboard
|
|
||||||
);
|
|
||||||
|
|
||||||
// execute the custom script
|
// execute the custom script
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user