"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const child_process_1 = require("child_process");
const path_1 = require("path");
const os_1 = require("os");
const fs_1 = require("fs");
const utils_1 = require("./utils");
const device_1 = require("./device");
const enums_1 = require("./enums");
const ios_device_lib_1 = require("ios-device-lib");
class IOSController {
    static getDl() {
        if (!IOSController._dl) {
            return new Promise((resolve, reject) => {
                IOSController._dl = new ios_device_lib_1.IOSDeviceLib(d => {
                    console.log("Device found!", d);
                    resolve(IOSController._dl);
                }, device => {
                    console.log("Device LOST!");
                });
            });
        }
        return Promise.resolve(IOSController._dl);
    }
    static disposeDL() {
        if (IOSController._dl) {
            IOSController._dl.dispose("SIGTERM");
            IOSController._dl = undefined;
        }
    }
    static getAllDevices(verbose = false) {
        if (IOSController.devicesScreenInfo.size === 0) {
            IOSController.loadIOSDevicesScreenInfo();
        }
        const devices = IOSController.parseSimulators();
        const allDevices = IOSController.parseRealDevices(devices);
        if (verbose) {
            console.log("All devices: ", devices);
        }
        return Promise.resolve(allDevices);
    }
    static getSimulatorPidByToken(token) {
        const simulatorPidAsString = utils_1.executeCommand(`ps ax | grep ${token} | grep -v grep`);
        const result = utils_1.getRegexResultsAsArray(/^\d+/gi, simulatorPidAsString);
        let pid = undefined;
        if (result.length > 0) {
            try {
                pid = parseInt(result[0].trim());
            }
            catch (error) {
                console.error("Couldn't parse simulator pid", error);
            }
        }
        return pid;
    }
    static startSimulator(simulator, directory = os_1.tmpdir()) {
        return __awaiter(this, void 0, void 0, function* () {
            let udid = simulator.token;
            utils_1.executeCommand(IOSController.SIMCTL + " erase " + udid);
            const process = IOSController.startSimulatorProcess(udid, directory);
            let response = yield utils_1.waitForOutput(process, /Instruments Trace Complete:/ig, /Failed to load/ig, IOSController.DEVICE_BOOT_TIME);
            if (response === true) {
                response = IOSController.checkIfSimulatorIsBooted(udid, IOSController.WAIT_DEVICE_TO_RESPONSE);
                if (response) {
                    simulator.type = enums_1.DeviceType.SIMULATOR;
                    simulator.status = enums_1.Status.BOOTED;
                    simulator.pid = IOSController.getSimulatorPidByToken(simulator.token);
                    simulator.startedAt = Date.now();
                    console.log(`Launched simulator with name: ${simulator.name}; udid: ${simulator.token}; status: ${simulator.status}`);
                }
            }
            else {
                console.log("Simulator is probably already started!");
            }
            return simulator;
        });
    }
    static restartDevice(device) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.type === enums_1.DeviceType.SIMULATOR) {
                IOSController.kill(device.token);
                device.status = enums_1.Status.SHUTDOWN;
                device.pid = undefined;
                device.startedAt = -1;
                device.busySince = -1;
                yield IOSController.startSimulator(device);
            }
        });
    }
    static killAll() {
        const log = utils_1.executeCommand("killall Simulator ");
        utils_1.executeCommand(IOSController.OSASCRIPT_QUIT_SIMULATOR_COMMAND);
    }
    static kill(udid) {
        console.log(`Killing simulator with udid ${udid}`);
        utils_1.executeCommand(`${IOSController.SIMCTL} shutdown ${udid}`);
        // Kill all the processes related with sim.id (for example WDA agents).
        const killAllRelatedProcessesCommand = `ps aux | grep -ie ${udid} | awk '{print $2}' | xargs kill -9`;
        utils_1.executeCommand(killAllRelatedProcessesCommand);
    }
    static getInstalledApps(device) {
        const apps = new Array();
        if (device.type === enums_1.DeviceType.DEVICE) {
            const rowData = utils_1.executeCommand(`ideviceinstaller -u ${device.token} -l`).replace("package:", "").split("\n");
            rowData.forEach(data => {
                const appBundle = /(\w+\.)+\w+/ig.exec(data);
                if (appBundle && appBundle.length > 0 && appBundle[0].includes(".")) {
                    apps.push(appBundle[0]);
                }
            });
        }
        else {
            const rowData = utils_1.executeCommand(`find ${IOSController.getSimLocation(device.token)} /data/Containers/Bundle/Application -type d -name *.app`).split("\n");
            rowData.forEach(data => {
                const rowBundle = utils_1.executeCommand(`defaults read " ${data} /Info.plist | grep CFBundleIdentifier`);
                const appId = rowBundle.split("\"")[1];
                apps.push(appId);
            });
        }
        return apps;
    }
    static installApp(device, fullAppName) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.type === enums_1.DeviceType.DEVICE) {
                const installProcess = yield (yield IOSController.getDl()).install(fullAppName, [device.token])[0];
                yield IOSController.disposeDL();
                if (!installProcess.response.includes("Successfully installed application")) {
                    console.error(installProcess.response);
                }
            }
            else {
                const result = utils_1.executeCommand(`${IOSController.SIMCTL} install ${device.token} ${fullAppName}`);
                console.dir(result);
            }
        });
    }
    static stopApplication(device, bundleId) {
        return __awaiter(this, void 0, void 0, function* () {
            const apps = IOSController.getInstalledApps(device);
            if (apps.some(app => app === bundleId)) {
                const appInfo = { ddi: undefined, appId: bundleId, deviceId: device.token };
                const dl = yield IOSController.getDl();
                return new Promise((res, reject) => {
                    Promise.all(dl.stop([appInfo]))
                        .then((response) => __awaiter(this, void 0, void 0, function* () {
                        console.log("App " + bundleId + " stopped !", response);
                        yield IOSController.disposeDL();
                        res(true);
                    })).catch((err) => __awaiter(this, void 0, void 0, function* () {
                        console.log("An error occurred! Probably app is still running!", err);
                        yield IOSController.disposeDL();
                        res(false);
                    }));
                });
            }
        });
    }
    static uninstallApp(device, fullAppName, bundleId = undefined) {
        return __awaiter(this, void 0, void 0, function* () {
            bundleId = bundleId || IOSController.getIOSPackageId(device.type, fullAppName);
            if (device.type === enums_1.DeviceType.DEVICE) {
                try {
                    yield IOSController.stopApplication(device, bundleId);
                }
                catch (error) {
                    console.dir(error);
                }
                utils_1.wait(1000);
                const result = utils_1.executeCommand(`ideviceinstaller -u ${device.token} -U ${bundleId}`);
            }
            else {
                utils_1.executeCommand(`${IOSController.SIMCTL} ${device.token} terminate ${bundleId}`);
                utils_1.wait(1000);
                const result = utils_1.executeCommand(`${IOSController.SIMCTL} uninstall ${device.token} ${bundleId}`);
            }
        });
    }
    static reinstallApplication(device, fullAppName, bundleId = undefined) {
        return __awaiter(this, void 0, void 0, function* () {
            bundleId = bundleId || IOSController.getIOSPackageId(device.type, fullAppName);
            yield IOSController.uninstallApp(device, fullAppName, bundleId);
            yield IOSController.installApp(device, fullAppName);
        });
    }
    static refreshApplication(device, fullAppName, bundleId = undefined) {
        return __awaiter(this, void 0, void 0, function* () {
            bundleId = bundleId || IOSController.getIOSPackageId(device.type, fullAppName);
            yield IOSController.reinstallApplication(device, fullAppName, bundleId);
            yield IOSController.startApplication(device, fullAppName, bundleId);
        });
    }
    static startApplication(device, fullAppName, bundleId = undefined) {
        return __awaiter(this, void 0, void 0, function* () {
            bundleId = bundleId || IOSController.getIOSPackageId(device.type, fullAppName);
            if (device.type === enums_1.DeviceType.DEVICE) {
                let startProcess;
                try {
                    startProcess = yield (yield IOSController.getDl()).start([{ "ddi": undefined, "appId": bundleId, "deviceId": device.token }])[0];
                    if (!startProcess.response.includes("Successfully started application")) {
                        throw new Error(`Failed to start application ${bundleId}`);
                    }
                }
                catch (error) {
                    yield IOSController.disposeDL();
                }
                yield IOSController.disposeDL();
            }
            else {
                const result = utils_1.executeCommand(`${IOSController.SIMCTL} launch ${device.token} ${bundleId}`);
                console.dir(result);
                Promise.resolve(result);
            }
        });
    }
    static startSimulatorProcess(udid, cwd = os_1.tmpdir(), timeout = 120000) {
        //xcrun instruments -v -t 'Blank' -l 100 -w
        const simProcess = child_process_1.spawn(IOSController.BOOT_DEVICE_COMMAND, [udid], {
            shell: true,
            detached: false,
            cwd: cwd
        });
        return simProcess;
    }
    static isRunning(token) {
        const out = utils_1.executeCommand(`${IOSController.SIMCTL} spawn ${token} launchctl print system | grep com.apple.springboard.services `);
        return out.includes("M   A   com.apple.springboard.services");
    }
    static parseSimulators(stdout = undefined) {
        if (!stdout) {
            stdout = utils_1.executeCommand(IOSController.XCRUNLISTDEVICES_COMMAND);
        }
        let deviceSectionRe = /-- iOS (.+) --(\n\s{4}.+)*/mg;
        let matches = [];
        let match = deviceSectionRe.exec(stdout);
        while (match !== null) {
            matches.push(match);
            match = deviceSectionRe.exec(stdout);
        }
        if (matches.length < 1) {
            throw new Error("No matching devices!!!");
        }
        const devices = new Map();
        for (match of matches) {
            let apiLevel = match[1];
            // split the full match into lines and remove the first
            for (let line of match[0].split('\n').slice(1)) {
                let lineRe = /([^\s].+) \((\w+-.+\w+)\) \((\w+\s?\w+)\)/; // https://regex101.com/r/lG7mK6/3
                let lineMatch = lineRe.exec(line);
                if (lineMatch === null) {
                    throw new Error(`Could not match line: ${line}`);
                }
                const status = lineMatch[3].toLowerCase();
                const device = new IOSDevice(lineMatch[2], lineMatch[1], status, enums_1.DeviceType.SIMULATOR, apiLevel);
                IOSController.devicesScreenInfo.forEach((v, k, m) => {
                    if (device.name.includes(k)) {
                        device.config = {
                            density: v.density,
                            offsetPixels: v.actionBarHeight
                        };
                    }
                });
                if (!devices.has(device.name)) {
                    devices.set(device.name, new Array());
                    devices.get(device.name).push(device);
                }
                else {
                    devices.get(device.name).push(device);
                }
            }
        }
        return devices;
    }
    static parseRealDevices(devices = new Map()) {
        const devicesUDID = utils_1.executeCommand("idevice_id  --list").split('\n');
        devicesUDID.forEach(udid => {
            if (udid && udid !== "") {
                const deviceInfo = utils_1.executeCommand(`ideviceinfo -s -u ${udid}`).split('\n');
                const device = new device_1.Device(undefined, undefined, enums_1.DeviceType.DEVICE, enums_1.Platform.IOS, udid, enums_1.Status.BOOTED);
                deviceInfo.forEach(info => {
                    if (info && info.trim() !== "") {
                        if (info.toLowerCase().includes('devicename')) {
                            device.name = info.split(": ")[1].trim();
                        }
                        if (info.toLowerCase().includes('productversion')) {
                            device.apiLevel = info.split(": ")[1].trim();
                        }
                    }
                });
                if (device.name) {
                    if (devices.has(device.name)) {
                        devices.get(device.name).push(device);
                    }
                    else {
                        devices.set(device.name, [device]);
                    }
                }
            }
        });
        return devices;
    }
    static getSimLocation(token) {
        const simRoot = path_1.resolve(process.env.HOME, "/Library/Developer/CoreSimulator/Devices/", token);
        return simRoot;
    }
    static filterDeviceBy(...args) {
        const mappedDevices = IOSController.parseSimulators();
        const result = new Array();
        mappedDevices.forEach(devices => {
            devices.forEach(device => {
                let shouldAdd = true;
                const deviceToString = device.toString().toLocaleLowerCase();
                args.forEach(arg => {
                    if (deviceToString.includes(arg.toLocaleLowerCase())) {
                        shouldAdd = shouldAdd && true;
                    }
                    else {
                        shouldAdd = false;
                    }
                });
                if (shouldAdd) {
                    result.push(device);
                }
            });
        });
        return result;
    }
    static getScreenshot(device, dir, fileName) {
        return __awaiter(this, void 0, void 0, function* () {
            const pathToScreenshotPng = path_1.resolve(dir, `${fileName}.png`);
            if (device.type === enums_1.DeviceType.DEVICE) {
                utils_1.executeCommand(`idevicescreenshot -u ${device.token} ${pathToScreenshotPng}`);
            }
            else {
                utils_1.executeCommand(`${IOSController.SIMCTL} io ${device.token} screenshot ${pathToScreenshotPng}`);
            }
            return pathToScreenshotPng;
        });
    }
    static recordVideo(device, dir, fileName, callback) {
        return __awaiter(this, void 0, void 0, function* () {
            const { pathToVideo, videoRecoringProcess } = IOSController.startRecordingVideo(device, dir, fileName);
            return new Promise((res, reject) => __awaiter(this, void 0, void 0, function* () {
                callback().then((result) => {
                    videoRecoringProcess.kill("SIGINT");
                    console.log(result);
                    res(pathToVideo);
                }).catch((error) => {
                    if (videoRecoringProcess) {
                        videoRecoringProcess.kill("SIGINT");
                    }
                    console.log('', error);
                    reject(error);
                });
            }));
        });
    }
    static startRecordingVideo(device, dir, fileName) {
        let pathToVideo = path_1.resolve(dir, `${fileName}.mp4`).replace(" ", "\ ");
        if (fs_1.existsSync(pathToVideo)) {
            fs_1.unlinkSync(pathToVideo);
        }
        let videoRecoringProcess;
        if (device.type === enums_1.DeviceType.DEVICE) {
            const p = path_1.resolve(__dirname, "../", "bin", "xrecord");
            console.log(`${p} --quicktime --id=${device.token} --out=${pathToVideo} --force`);
            const startRecording = () => {
                return child_process_1.spawn(`${p}`, [`--quicktime`, `--id=\"${device.token}\"`, `--out=\"${pathToVideo}\"`, `--force`], {
                    stdio: 'inherit',
                    shell: true
                });
            };
            videoRecoringProcess = startRecording();
            utils_1.wait(3000);
            const checkHasStartedRecording = (timeout, pathToVideo) => {
                const startTime = Date.now();
                while (Date.now() - startTime <= timeout && !fs_1.existsSync(pathToVideo)) {
                }
                return fs_1.existsSync(pathToVideo);
            };
            let retryCount = 10;
            let awaitOnRecordingStart = false;
            while (!checkHasStartedRecording(5000, pathToVideo) && retryCount >= 0) {
                try {
                    child_process_1.execSync("killall 'QuickTime Player'");
                }
                catch (error) { }
                try {
                    videoRecoringProcess.kill("SIGTERM");
                }
                catch (error) { }
                retryCount--;
                utils_1.wait(2000);
                const quicktimeAppleScriptPath = path_1.resolve(__dirname, "../bin/startQuickTimePlayer.scpt");
                child_process_1.spawnSync('osascript', [quicktimeAppleScriptPath, '10'], {
                    shell: true,
                    stdio: 'inherit'
                });
                videoRecoringProcess = startRecording();
                awaitOnRecordingStart = true;
            }
            if (awaitOnRecordingStart)
                utils_1.wait(3000);
            if (!fs_1.existsSync(pathToVideo)) {
                console.error(`Couldn't start recording process!`);
                console.error(`Recording couldn't be started! Check device connection and quick time player`);
                videoRecoringProcess = null;
                pathToVideo = null;
            }
        }
        else {
            console.log(`${IOSController.XCRUN} simctl io ${device.token} recordVideo ${pathToVideo}`);
            videoRecoringProcess = child_process_1.spawn(`xcrun`, ['simctl ', 'io', device.token, 'recordVideo', `'${pathToVideo}'`], {
                cwd: process.cwd(),
                shell: true,
                stdio: 'inherit'
            });
        }
        if (videoRecoringProcess) {
            IOSController.runningProcesses.push(videoRecoringProcess.pid);
        }
        return { pathToVideo: pathToVideo, videoRecoringProcess: videoRecoringProcess };
    }
    // Should find a better way
    static checkIfSimulatorIsBooted(udid, timeout) {
        const startTime = new Date().getTime();
        let currentTime = new Date().getTime();
        console.log("Check if simulator is booted!");
        let booted = false;
        while ((currentTime - startTime) < timeout && !booted) {
            currentTime = new Date().getTime();
            const devices = IOSController.filterDeviceBy(udid, enums_1.Status.BOOTED);
            booted = devices.length > 0 && IOSController.isRunning(udid);
        }
        if (!booted) {
            let error = `Simulator with " ${udid} failed to boot`;
            console.log(error, true);
        }
        else {
            console.log("Simulator is booted!");
        }
        return booted;
    }
    static getIOSPackageId(deviceType, fullAppName) {
        let result = "";
        const plistPath = IOSController.getPlistPath(fullAppName);
        if (utils_1.fileExists(plistPath)) {
            const command = "/usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' " + plistPath;
            result = utils_1.executeCommand(command);
        }
        else {
            console.error("File " + plistPath + " does not exist.");
        }
        return result.trim();
    }
    static getDevicesScreenInfo() {
        if (IOSController.devicesScreenInfo.size == 0) {
            IOSController.loadIOSDevicesScreenInfo();
        }
        return IOSController.devicesScreenInfo;
    }
    /**
     * Get path of Info.plist of iOS app under test.
     * Info.plist holds information for app under test.
     *
     * @return path to Info.plist
     */
    static getPlistPath(fullAppName) {
        let plistPath = null;
        const ext = path_1.extname(fullAppName);
        if (ext.includes('ipa')) {
            const appFullName = path_1.dirname(fullAppName) + path_1.sep + path_1.basename(fullAppName).replace(".ipa", "");
            const command = `unzip -o ${fullAppName} -d ${appFullName}`;
            console.log(command);
            utils_1.executeCommand(command);
            const appName = utils_1.executeCommand(`ls ${path_1.resolve(appFullName, "Payload")}`).split('\n').filter(f => f.includes(".app"))[0];
            plistPath = path_1.resolve(appFullName, "Payload", appName, "Info.plist");
        }
        else {
            plistPath = path_1.resolve(fullAppName, "Info.plist");
        }
        return plistPath;
    }
    // Not testes to the end
    static waitForBootInSystemLog(simulator, bootedIndicator, startupTimeout) {
        return __awaiter(this, void 0, void 0, function* () {
            return yield IOSController.tailLogsUntil(simulator.token, bootedIndicator, startupTimeout);
        });
    }
    static tailLogsUntil(token, bootedIndicator, timeoutMs) {
        return __awaiter(this, void 0, void 0, function* () {
            let simLog = path_1.resolve(IOSController.getLogDir(token), 'system.log');
            // we need to make sure log file exists before we can tail it
            let exists = fs_1.existsSync(simLog);
            while (!exists) {
                exists = fs_1.existsSync(simLog);
            }
            console.info(`Simulator log at '${simLog}'`);
            console.info(`Tailing simulator logs until we encounter the string "${bootedIndicator}"`);
            console.info(`We will time out after ${timeoutMs}ms`);
            let isBooted = false;
            try {
                let result = utils_1.tailFilelUntil(simLog, "com.apple.intents.intents-image-service", 0);
                while (!result.result) {
                    result = utils_1.tailFilelUntil(simLog, bootedIndicator, result.index);
                }
                isBooted = result.result;
            }
            catch (err) {
                console.debug('Simulator startup timed out. Continuing anyway.');
            }
            return isBooted;
        });
    }
    static getLogDir(token) {
        let home = process.env.HOME;
        return path_1.resolve(home, 'Library', 'Logs', 'CoreSimulator', token);
    }
    static loadIOSDevicesScreenInfo() {
        const devices = new Map();
        // IOSController.devicesScreenInfo.set("iPhone 5", new IOSDeviceScreenInfo("iPhone 5", 640, 1336, 326, 30));
        // IOSController.devicesScreenInfo.set("iPhone 5C", new IOSDeviceScreenInfo("iPhone 5C", 640, 1336, 326, 30));
        // IOSController.devicesScreenInfo.set("iPhone 5S", new IOSDeviceScreenInfo("iPhone 5S", 640, 1336, 326, 30));
        IOSController.devicesScreenInfo.set("iPhone 6", new IOSDeviceScreenInfo("iPhone 6", 750, 1334, 2, 33));
        IOSController.devicesScreenInfo.set("iPhone 6s", new IOSDeviceScreenInfo("iPhone 6s", 750, 1334, 2, 33));
        IOSController.devicesScreenInfo.set("iPhone 7", new IOSDeviceScreenInfo("iPhone 7", 750, 1334, 2, 33));
        IOSController.devicesScreenInfo.set("iPhone 8", new IOSDeviceScreenInfo("iPhone 8", 750, 1334, 2, 33));
        IOSController.devicesScreenInfo.set("6 Plus", new IOSDeviceScreenInfo("iPhone 6 Plus", 1242, 2208, 3, 50));
        IOSController.devicesScreenInfo.set("6s Plus", new IOSDeviceScreenInfo("iPhone 6 Plus", 1242, 2208, 3, 50));
        IOSController.devicesScreenInfo.set("7 Plus", new IOSDeviceScreenInfo("iPhone 7 Plus", 1242, 2208, 3, 50));
        IOSController.devicesScreenInfo.set("8 Plus", new IOSDeviceScreenInfo("iPhone 8 Plus", 1242, 2208, 3, 50));
        IOSController.devicesScreenInfo.set("X", new IOSDeviceScreenInfo("iPhone X", 11242, 2208, 3, 87));
        // IOSController.devicesScreenInfo("Mini 2", new IOSDeviceScreenInfo("Mini 2", 11242, 2208, 401));
        // IOSController.devicesScreenInfo("Mini 3", new IOSDeviceScreenInfo("Mini 3", 11242, 2208, 401));
        // IOSController.devicesScreenInfo("Mini 4", new IOSDeviceScreenInfo("Mini 4", 11242, 2208, 401));
        // IOSController.devicesScreenInfo("iPad 3", new IOSDeviceScreenInfo("iPad 3", 1536, 2048, 264));
        // IOSController.devicesScreenInfo("iPad 4", new IOSDeviceScreenInfo("iPad 4", 1536, 2048, 264));
        // IOSController.devicesScreenInfo("iPad Air", new IOSDeviceScreenInfo("iPad Air", 1536, 2048, 264));
        // IOSController.devicesScreenInfo.set("iPad Air 2", new IOSDeviceScreenInfo("iPad Air 2", 1536, 2048, 264, 32));
        // IOSController.devicesScreenInfo("9.7-inch Pro", new IOSDeviceScreenInfo("iPad Pro", 1536, 2048, 264));
        // IOSController.devicesScreenInfo("12.9-inch iPad Pro", new IOSDeviceScreenInfo("12.9-inch iPad Pro", 1536, 2048, 264));
    }
}
IOSController.XCRUN = "xcrun ";
IOSController.SIMCTL = `${IOSController.XCRUN} simctl`;
IOSController.XCRUNLISTDEVICES_COMMAND = `${IOSController.SIMCTL} list devices `;
IOSController.BOOT_DEVICE_COMMAND = `${IOSController.XCRUN} instruments -v -t 'Blank' -l 1 -w `;
IOSController.GET_BOOTED_DEVICES_COMMAND = `${IOSController.SIMCTL} list devices `;
IOSController.OSASCRIPT_QUIT_SIMULATOR_COMMAND = "osascript -e 'tell application \"Simulator\" to quit'";
IOSController.IOS_DEVICE = "ios-device";
IOSController.devicesScreenInfo = new Map();
IOSController.DEVICE_BOOT_TIME = 180000;
IOSController.WAIT_DEVICE_TO_RESPONSE = 180000;
IOSController.runningProcesses = new Array();
exports.IOSController = IOSController;
class IOSDevice extends device_1.Device {
    constructor(token, name, status, type, apiLevel, pid) {
        super(name, apiLevel, type, enums_1.Platform.IOS, token, status, pid);
    }
}
exports.IOSDevice = IOSDevice;
class IOSDeviceScreenInfo {
    // In the context of iOS, the proper term for `density` is `screen scale`. Adhere to `density` for unified API.
    constructor(deviceType, width, height, density, actionBarHeight) {
        this.deviceType = deviceType;
        this.width = width;
        this.height = height;
        this.density = density;
        this.actionBarHeight = actionBarHeight;
    }
}
exports.IOSDeviceScreenInfo = IOSDeviceScreenInfo;
//# sourceMappingURL=ios-controller.js.map