diff --git a/README.md b/README.md index 8bd34eedf..6906f934c 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ jobs: | `disable-spellchecker` | Optional | `false` | Whether to disable spellchecker - `true` or `false`. | | `disable-autofill` | Optional | `false` | Whether to disable autofill - `true` or `false`. | | `longpress-timeout` | Optional | 500 | Longpress timeout in milliseconds. | +| `enable-hw-keyboard` | Optional | `false` | Whether to enable the hw keyboard and disable soft keyboard - `true` or `false`. | | `emulator-build` | Optional | N/A | Build number of a specific version of the emulator binary to use e.g. `6061023` for emulator v29.3.0.0. | | `working-directory` | Optional | `./` | A custom working directory - e.g. `./android` if your root Gradle project is under the `./android` sub-directory within your repository. | | `ndk` | Optional | N/A | Version of NDK to install - e.g. `21.0.6113669` | diff --git a/__tests__/input-validator.test.ts b/__tests__/input-validator.test.ts index 729013765..9985811c1 100644 --- a/__tests__/input-validator.test.ts +++ b/__tests__/input-validator.test.ts @@ -145,6 +145,27 @@ describe('disable-autofill validator tests', () => { }); }); +describe('enable-hw-keyboard validator tests', () => { + it('Throws if enable-hw-keyboard is not a boolean', () => { + const func = () => { + validator.checkEnableHwKeyboard('yes'); + }; + expect(func).toThrowError(`Input for input.enable-hw-keyboard should be either 'true' or 'false'.`); + }); + + it('Validates successfully if enable-hw-keyboard is either true or false', () => { + const func1 = () => { + validator.checkEnableHwKeyboard('true'); + }; + expect(func1).not.toThrow(); + + const func2 = () => { + validator.checkEnableHwKeyboard('false'); + }; + expect(func2).not.toThrow(); + }); +}); + describe('longpress-timeout validator tests', () => { it('Throws if longpress-timeout is not a number', () => { const func = () => { diff --git a/action.yml b/action.yml index f86c65bc6..2b9637a63 100644 --- a/action.yml +++ b/action.yml @@ -36,6 +36,9 @@ inputs: longpress-timeout: description: Longpress timeout in milliseconds. default: 500 + enable-hw-keyboard: + description: Enable hw keyboard and disable soft keyboard - `true` or `false`. + default: 'false' emulator-build: description: 'build number of a specific version of the emulator binary to use - e.g. `6061023` for emulator v29.3.0.0' working-directory: diff --git a/lib/emulator-manager.js b/lib/emulator-manager.js index 604e359a1..c0fb4b4bb 100644 --- a/lib/emulator-manager.js +++ b/lib/emulator-manager.js @@ -34,13 +34,16 @@ const EMULATOR_BOOT_TIMEOUT_SECONDS = 600; /** * Creates and launches a new AVD instance with the specified configurations. */ -function launchEmulator(apiLevel, target, arch, profile, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellChecker, disableAutofill, longPressTimeout) { +function launchEmulator(apiLevel, target, arch, profile, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellChecker, disableAutofill, longPressTimeout, enableHwKeyboard) { return __awaiter(this, void 0, void 0, function* () { // create a new AVD const profileOption = profile.trim() !== '' ? `--device '${profile}'` : ''; const sdcardPathOrSizeOption = sdcardPathOrSize.trim() !== '' ? `--sdcard '${sdcardPathOrSize}'` : ''; console.log(`Creating AVD.`); yield exec.exec(`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${apiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`); + if (enableHwKeyboard) { + yield exec.exec(`sh -c \\"printf 'hw.keyboard=yes\n' >> ~/.android/avd/"${avdName}".avd"/config.ini`); + } // start emulator console.log('Starting emulator.'); // turn off hardware acceleration on Linux @@ -75,6 +78,9 @@ function launchEmulator(apiLevel, target, arch, profile, sdcardPathOrSize, avdNa if (longPressTimeout) { yield exec.exec(`adb shell settings put secure long_press_timeout ${longPressTimeout}`); } + if (enableHwKeyboard) { + yield exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`); + } }); } exports.launchEmulator = launchEmulator; diff --git a/lib/input-validator.js b/lib/input-validator.js index 87a80c7ff..fb4717b6d 100644 --- a/lib/input-validator.js +++ b/lib/input-validator.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.checkEmulatorBuild = exports.checkLongPressTimeout = exports.checkDisableAutofill = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0; +exports.checkEmulatorBuild = exports.checkLongPressTimeout = exports.checkEnableHwKeyboard = exports.checkDisableAutofill = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0; exports.MIN_API_LEVEL = 15; exports.VALID_TARGETS = ['default', 'google_apis', 'google_apis_playstore']; exports.VALID_ARCHS = ['x86', 'x86_64']; @@ -43,6 +43,12 @@ function checkDisableAutofill(disableAutofill) { } } exports.checkDisableAutofill = checkDisableAutofill; +function checkEnableHwKeyboard(enableHwKeyboard) { + if (!isValidBoolean(enableHwKeyboard)) { + throw new Error(`Input for input.enable-hw-keyboard should be either 'true' or 'false'.`); + } +} +exports.checkEnableHwKeyboard = checkEnableHwKeyboard; function checkLongPressTimeout(timeout) { if (isNaN(Number(timeout)) || !Number.isInteger(Number(timeout))) { throw new Error(`Unexpected longpress-timeout: '${timeout}'.`); diff --git a/lib/main.js b/lib/main.js index 4e54d333b..ac35bc9f0 100644 --- a/lib/main.js +++ b/lib/main.js @@ -77,6 +77,11 @@ function run() { input_validator_1.checkDisableAnimations(disableAnimationsInput); const disableAnimations = disableAnimationsInput === 'true'; console.log(`disable animations: ${disableAnimations}`); + // disable ime + const enableHwKeyboardInput = core.getInput('enable-hw-keyboard'); + input_validator_1.checkEnableHwKeyboard(enableHwKeyboardInput); + const enableHwKeyboard = enableHwKeyboardInput === 'true'; + console.log(`enable hw keyboard: ${enableHwKeyboard}`); // disable spellchecker const disableSpellcheckerInput = core.getInput('disable-spellchecker'); input_validator_1.checkDisableSpellchecker(disableSpellcheckerInput); @@ -127,7 +132,7 @@ function run() { // install SDK yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion); // launch an emulator - yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellchecker, disableAutofill, longPressTimeout); + yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellchecker, disableAutofill, longPressTimeout, enableHwKeyboard); // execute the custom script try { // move to custom working directory if set diff --git a/src/emulator-manager.ts b/src/emulator-manager.ts index 5d4cf1fbc..c8c51ee83 100644 --- a/src/emulator-manager.ts +++ b/src/emulator-manager.ts @@ -16,7 +16,8 @@ export async function launchEmulator( disableAnimations: boolean, disableSpellChecker: boolean, disableAutofill: boolean, - longPressTimeout: number + longPressTimeout: number, + enableHwKeyboard: boolean ): Promise { // create a new AVD const profileOption = profile.trim() !== '' ? `--device '${profile}'` : ''; @@ -26,6 +27,10 @@ export async function launchEmulator( `sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${apiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"` ); + if (enableHwKeyboard) { + await exec.exec(`sh -c \\"printf 'hw.keyboard=yes\n' >> ~/.android/avd/"${avdName}".avd"/config.ini`); + } + // start emulator console.log('Starting emulator.'); @@ -64,6 +69,9 @@ export async function launchEmulator( if (longPressTimeout) { await exec.exec(`adb shell settings put secure long_press_timeout ${longPressTimeout}`); } + if (enableHwKeyboard) { + await exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`); + } } /** diff --git a/src/input-validator.ts b/src/input-validator.ts index 5c32a1e09..defe83dc9 100644 --- a/src/input-validator.ts +++ b/src/input-validator.ts @@ -41,6 +41,12 @@ export function checkDisableAutofill(disableAutofill: string): void { } } +export function checkEnableHwKeyboard(enableHwKeyboard: string): void { + if (!isValidBoolean(enableHwKeyboard)) { + throw new Error(`Input for input.enable-hw-keyboard should be either 'true' or 'false'.`); + } +} + export function checkLongPressTimeout(timeout: string): void { if (isNaN(Number(timeout)) || !Number.isInteger(Number(timeout))) { throw new Error(`Unexpected longpress-timeout: '${timeout}'.`); diff --git a/src/main.ts b/src/main.ts index c613fe7d4..964d216b5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,16 @@ import * as core from '@actions/core'; import { installAndroidSdk } from './sdk-installer'; -import { checkApiLevel, checkTarget, checkArch, checkDisableAnimations, checkEmulatorBuild, checkDisableSpellchecker, checkDisableAutofill, checkLongPressTimeout } from './input-validator'; +import { + checkApiLevel, + checkTarget, + checkArch, + checkDisableAnimations, + checkEmulatorBuild, + checkDisableSpellchecker, + checkDisableAutofill, + checkLongPressTimeout, + checkEnableHwKeyboard +} from './input-validator'; import { launchEmulator, killEmulator } from './emulator-manager'; import * as exec from '@actions/exec'; import { parseScript } from './script-parser'; @@ -57,6 +67,12 @@ async function run() { const disableAnimations = disableAnimationsInput === 'true'; console.log(`disable animations: ${disableAnimations}`); + // disable ime + const enableHwKeyboardInput = core.getInput('enable-hw-keyboard'); + checkEnableHwKeyboard(enableHwKeyboardInput); + const enableHwKeyboard = enableHwKeyboardInput === 'true'; + console.log(`enable hw keyboard: ${enableHwKeyboard}`); + // disable spellchecker const disableSpellcheckerInput = core.getInput('disable-spellchecker'); checkDisableSpellchecker(disableSpellcheckerInput); @@ -116,7 +132,7 @@ async function run() { await installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion); // launch an emulator - await launchEmulator(apiLevel, target, arch, profile, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellchecker, disableAutofill, longPressTimeout); + await launchEmulator(apiLevel, target, arch, profile, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellchecker, disableAutofill, longPressTimeout, enableHwKeyboard); // execute the custom script try {