-
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
154 changed files
with
12,819 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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,120 @@ | ||
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Emulator = void 0; | ||
const exec_with_result_1 = require("./exec-with-result"); | ||
class Emulator { | ||
constructor(sdk, name, api, abi, tag, adbPort, telnetPort) { | ||
this.sdk = sdk; | ||
this.name = name; | ||
this.api = api; | ||
this.abi = abi; | ||
this.tag = tag; | ||
this.adbPort = adbPort; | ||
this.telnetPort = telnetPort; | ||
} | ||
start(cmdOptions, bootTimeout) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield (0, exec_with_result_1.execIgnoreFailure)(`bash -c \\\"${this.sdk.emulatorCmd()} @${this.name} ${cmdOptions} &\"`); | ||
let booted = yield this.waitForBoot(bootTimeout); | ||
console.log(`booted=${booted}`); | ||
return booted; | ||
}); | ||
} | ||
stop() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield (0, exec_with_result_1.execIgnoreFailure)(`bash -c \\\"${this.sdk.androidHome()}/platform-tools/adb -s emulator-${this.adbPort} emu kill\"`); | ||
console.log("emu kill finished"); | ||
return; | ||
}); | ||
} | ||
waitForBoot(timeout) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
for (let countdown = timeout; countdown > 0; countdown--) { | ||
if (countdown == 0) { | ||
console.error("Timeout waiting for the emulator"); | ||
return false; | ||
} | ||
try { | ||
let output = yield this.execAdbCommand("shell getprop sys.boot_completed"); | ||
if (output.trim() == '1') { | ||
countdown = 0; | ||
console.log("Emulator booted"); | ||
return true; | ||
} | ||
} | ||
catch (e) { | ||
if (e instanceof Error) { | ||
console.error(e.message); | ||
} | ||
else { | ||
console.error(e); | ||
} | ||
} | ||
console.log("Sleeping for 1s"); | ||
yield sleep(1000); | ||
countdown--; | ||
} | ||
console.log("Timeout waiting for emulator to boot. Exiting"); | ||
return false; | ||
}); | ||
} | ||
unlock() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this.execAdbCommand("shell input keyevent 82"); | ||
}); | ||
} | ||
disableAnimations() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
console.log('Disabling animations'); | ||
try { | ||
yield this.execAdbCommand("shell settings put global window_animation_scale 0.0"); | ||
yield this.execAdbCommand("shell settings put global transition_animation_scale 0.0"); | ||
yield this.execAdbCommand("shell settings put global animator_duration_scale 0.0"); | ||
} | ||
catch (e) { | ||
console.warn("error disabling animations. skipping"); | ||
} | ||
}); | ||
} | ||
execAdbCommand(args) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return yield (0, exec_with_result_1.execIgnoreFailure)(`${this.sdk.androidHome()}/platform-tools/adb -s emulator-${this.adbPort} ${args}`); | ||
}); | ||
} | ||
startLogcat() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
console.log('Starting logcat read process'); | ||
try { | ||
yield (0, exec_with_result_1.execIgnoreFailure)(`mkdir -p artifacts`); | ||
yield (0, exec_with_result_1.execIgnoreFailure)(`bash -c \\\"${this.sdk.androidHome()}/platform-tools/adb -s emulator-${this.adbPort} logcat -dv time > artifacts/logcat.log &\"`); | ||
} | ||
catch (e) { | ||
console.warn("can't start logcat read process. skipping"); | ||
} | ||
}); | ||
} | ||
stopLogcat() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
console.log('Stopping logcat read process'); | ||
try { | ||
yield (0, exec_with_result_1.execIgnoreFailure)(`kill $(jobs -p)`); | ||
} | ||
catch (e) { | ||
console.warn("can't stop logcat read process. skipping"); | ||
} | ||
}); | ||
} | ||
} | ||
exports.Emulator = Emulator; | ||
function sleep(ms) { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
} |
This file contains 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,46 @@ | ||
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Result = exports.execIgnoreFailure = void 0; | ||
const exec_1 = require("@actions/exec"); | ||
function execWithResult(commandLine, args, options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let result = new Result(); | ||
let exitCode = yield (0, exec_1.exec)(commandLine, args, Object.assign(Object.assign({}, options), { listeners: { | ||
stdout: (data) => { | ||
result.stdout += data.toString(); | ||
}, | ||
stderr: (data) => { | ||
result.stderr += data.toString(); | ||
} | ||
} })); | ||
result.stdout = result.stdout.trim(); | ||
result.stderr = result.stderr.trim(); | ||
result.exitCode = exitCode; | ||
return result; | ||
}); | ||
} | ||
exports.default = execWithResult; | ||
function execIgnoreFailure(commandLine, args, options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let result = yield execWithResult(commandLine, args, options); | ||
return result.stdout; | ||
}); | ||
} | ||
exports.execIgnoreFailure = execIgnoreFailure; | ||
class Result { | ||
constructor() { | ||
this.exitCode = 0; | ||
this.stdout = ''; | ||
this.stderr = ''; | ||
} | ||
} | ||
exports.Result = Result; |
This file contains 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,155 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const core = __importStar(require("@actions/core")); | ||
const sdk_1 = require("./sdk"); | ||
const exec_with_result_1 = __importDefault(require("./exec-with-result")); | ||
function run() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
let api = core.getInput('api', { required: false }); | ||
if (api == null || api == "") { | ||
console.log(`API not set. Using 25`); | ||
api = '25'; | ||
} | ||
let abi = core.getInput('abi', { required: false }); | ||
if (abi == null || abi == "") { | ||
console.log(`ABI not set. Using armeabi-v7a`); | ||
abi = 'armeabi-v7a'; | ||
} | ||
let tag = core.getInput('tag', { required: false }); | ||
if (tag !== "default" && tag !== "google_apis") { | ||
console.log(`Unknown tag ${tag}. Using default`); | ||
tag = 'default'; | ||
} | ||
let verbose = false; | ||
if (core.getInput('verbose') == "true") { | ||
verbose = true; | ||
} | ||
let cmd = core.getInput('cmd', { required: true }); | ||
if (cmd === "") { | ||
console.error("Please specify cmd to execute in parallel with emulator"); | ||
return; | ||
} | ||
let cmdOptions = core.getInput('cmdOptions'); | ||
if (cmdOptions == null) { | ||
cmdOptions = "-no-snapshot-save -noaudio -no-boot-anim"; | ||
} | ||
let hardwareProfile = core.getInput('hardwareProfile'); | ||
if (hardwareProfile == null) { | ||
hardwareProfile = ""; | ||
} | ||
let disableAnimations = false; | ||
if (core.getInput('disableAnimations') == "true") { | ||
disableAnimations = true; | ||
} | ||
let bootTimeout = core.getInput('bootTimeout'); | ||
if (bootTimeout == null) { | ||
bootTimeout = '600'; | ||
} | ||
console.log(`Starting emulator with API=${api}, TAG=${tag} and ABI=${abi}...`); | ||
const androidHome = process.env.ANDROID_HOME; | ||
console.log(`ANDROID_HOME is ${androidHome}`); | ||
console.log(`PATH is ${process.env.PATH}`); | ||
let sdk = new sdk_1.SdkFactory().getAndroidSdk(); | ||
try { | ||
yield sdk.installEmulatorPackage(api, tag, abi, verbose); | ||
yield sdk.installPlatform(api, verbose); | ||
let supportsHardwareAcceleration = yield sdk.verifyHardwareAcceleration(); | ||
if (!supportsHardwareAcceleration && abi == "x86") { | ||
core.setFailed('Hardware acceleration is not supported'); | ||
return; | ||
} | ||
let emulator = yield sdk.createEmulator("emulator", api, tag, abi, hardwareProfile); | ||
console.log("starting adb server"); | ||
yield sdk.startAdbServer(); | ||
let booted = yield emulator.start(cmdOptions, +bootTimeout); | ||
if (!booted) { | ||
core.setFailed("emulator boot failed"); | ||
yield emulator.stop(); | ||
return; | ||
} | ||
//Pre-setup | ||
yield emulator.unlock(); | ||
if (disableAnimations) { | ||
yield emulator.disableAnimations(); | ||
} | ||
yield emulator.startLogcat(); | ||
console.log("emulator started and booted"); | ||
try { | ||
let result = yield (0, exec_with_result_1.default)(`${cmd}`); | ||
let code = result.exitCode; | ||
if (code != 0) { | ||
core.setFailed(`process exited with code ${code}`); | ||
} | ||
} | ||
catch (e) { | ||
if (e instanceof Error) { | ||
core.setFailed(e.message); | ||
} | ||
else { | ||
core.setFailed("unknown (error !instanceof Error) occurred"); | ||
} | ||
} | ||
console.log("stopping emulator"); | ||
yield emulator.stop(); | ||
yield emulator.stopLogcat(); | ||
console.log("emulator is stopped"); | ||
} | ||
catch (error) { | ||
console.error(error); | ||
if (error instanceof Error) { | ||
core.setFailed(error.message); | ||
} | ||
else { | ||
core.setFailed("unknown (error !instanceof Error) occurred"); | ||
} | ||
return; | ||
} | ||
} | ||
catch (error) { | ||
if (error instanceof Error) { | ||
core.setFailed(error.message); | ||
} | ||
else { | ||
core.setFailed("unknown (error !instanceof Error) occurred"); | ||
} | ||
return; | ||
} | ||
}); | ||
} | ||
run(); |
Oops, something went wrong.