public function run(array $context = []) { $symbol = Manager::readConfig($context, self::CFG_SYMBOL, $this->defaultSymbol); try { $this->screen->capture($symbol, Manager::readConfig($context, self::CFG_ORIENTATION, $this->defaultOrientation)); $this->logger->info('Screen info: %uX%u mode %s, rotate fix is %s.', [$this->screen->width, $this->screen->height, $this->screen->orientation, $this->screen->rotateFix ? 'On' : 'Off']); return Manager::RET_LOOP; } catch (\RuntimeException $e) { return $this->errorReturnCode; } }
public function swipe(array $rectangle) { $this->scr->translateRect($rectangle); $retry = 0; while (!$this->adb->swipeLine($rectangle)) { if (++$retry > $this->retryLimit) { $this->logger->error('Abandon retry for tapping screen.'); return $this->adb->shell->returnCode; } else { $this->logger->warning('Retry %u for tapping screen.', [$retry]); } $this->delay->delayOffset($this->retryDelay, $this->retryOffset); } return true; }
public function run(array $context = []) { $filename = Manager::readConfig($context, self::CFG_FILENAME); $orientation = Manager::readConfig($context, self::CFG_ORIENTATION, Screen::AUTO); if (!is_readable($filename)) { throw new \RuntimeException("Image '{$filename}' is unable to read."); } try { $this->screen->load($filename, $orientation); $this->logger->info('Screen info: %uX%u mode %s, rotate fix is %s.', [$this->screen->width, $this->screen->height, $this->screen->orientation, $this->screen->rotateFix ? 'On' : 'Off']); return Manager::RET_LOOP; } catch (\Exception $e) { $this->logger->error("Image '{$filename}' is corrupt or not a PNG file."); return $this->errorReturnCode; } }
public function __construct(Manager $manager, array $config) { parent::__construct($manager, $config); $this->rules = Manager::readConfig($config, self::CFG_RULES); $this->button = Manager::readConfig($config, self::CFG_BUTTON); Screen::assertRules($this->rules); Position::assertRect($this->button); }
public function __construct(Manager $manager, array $config) { parent::__construct($manager, $config); $config = $config + $manager->getBaseComponentConfig($this->app); $this->package = Manager::readConfig($config, self::CFG_PACKAGE_NAME); $this->adb = ADB::instance($manager, $this->app); $this->detector = LoadingDetection::instance($manager, $this->app); $this->screen = Screen::instance($manager, $this->app); $this->input = Input::instance($manager, $this->app); }
/** * * @param array $assertion */ public function waitFor(array $assertion, $timeout = null, $delay = null) { Screen::assertRules($assertion); $timeout = is_int($timeout) && $timeout > 0 ? $timeout : $this->timeout; $delay = is_int($delay) && $delay > 0 ? $delay : $this->delay; $offset = intval($delay * 0.15); $waited = 0; while (!$this->screen->compareRules($assertion)) { $this->delay->delayOffset($delay, $offset); $waited += $delay; if ($waited > $timeout) { throw new \RuntimeException('Waiting for assertion timeout.'); } } }
public function ocr($rule, array &$rect, array $override = []) { if (!isset($this->rules[$rule])) { throw new \InvalidArgumentException("Undefined OCR rule '{$rule}'."); } $this->rule =& $this->rules[$rule]; $this->setConfig($override); $this->align = self::getRectAlign($rect); $this->result = ''; if ($this->mode === self::SCAN_FIXED) { $minX = min($rect[Position::X1], $rect[Position::X2]); $maxX = max($rect[Position::X1], $rect[Position::X2]); if ($this->width == 0) { throw new \InvalidArgumentException('OCR Width is not initialized or passed.'); } $scanAt = $this->align == self::ALIGN_LEFT ? $minX : $maxX - $this->width; $this->logger->debug('Ready to OCR with fixed stepping, Align=%s, Range=%.4f-%.4f, Start=%.4f, Width=%.4f, Margin=%.4f, Step=%.4f', [$this->align, $minX, $maxX, $scanAt, $this->width, $this->margin, $this->ocrStep()]); while ($scanAt >= $minX && $scanAt + $this->width <= $maxX) { $ocrRect = Position::makeRectangle($scanAt, $rect[Position::Y1], $scanAt + $this->width, $rect[Position::Y2]); $char = $this->ocrChar($this->rule, $ocrRect); if (is_null($char) && $this->ocrFailure() === Manager::RET_FINISH) { break; } $this->ocrConcat($char); $scanAt += $this->ocrStep(); $this->logger->debug('Forward=%.4f', [$scanAt]); } } elseif ($this->mode === self::SCAN_ADAPTIVE) { $this->screen->translateRect($rect); $this->scanCache = []; $minX = min($rect[Position::X1], $rect[Position::X2]); $maxX = max($rect[Position::X1], $rect[Position::X2]); $minY = min($rect[Position::Y1], $rect[Position::Y2]); $maxY = max($rect[Position::Y1], $rect[Position::Y2]); $scanAt = $rect[Position::X1]; $step = $this->align === self::ALIGN_LEFT ? 1 : -1; $this->logger->debug('Ready to OCR with adaptive width. Align=%s, Range=%u-%u, Step=%d', [$this->align, $minX, $maxX, $step]); while ($scanAt >= $minX && $scanAt <= $maxX) { $Y1 = $maxY; $Y2 = $minY; // Get X1 while ($scanAt >= $minX && $scanAt <= $maxX) { if ($Y1 = $this->searchInLine(Position::Y, $scanAt, $minY, $maxY)) { break; } $scanAt += $step; } $X1 = $scanAt; // Get X2, Y1 while ($scanAt >= $minX && $scanAt <= $maxX && ($foundY = $this->searchInLine(Position::Y, $scanAt, $minY, $maxY))) { if ($foundY < $Y1) { $Y1 = $foundY; } $scanAt += $step; } $X2 = $scanAt; if ($scanAt < $minX || $scanAt > $maxX) { break; } // Get Y2 for ($scanY = $maxY; $scanY > $Y1; $scanY--) { if ($this->searchInLine(Position::X, $scanY, $X1, $X2)) { $Y2 = $scanY; break; } } // OCR $ocrRect = Position::makeRectangle($X1, $Y1, $X2, $Y2); $this->logger->info('Possible character from (%u,%u) to (%u,%u)', [$X1, $Y1, $X2, $Y2]); $char = $this->ocrChar($this->rule, $ocrRect); if (is_null($char) && $this->ocrFailure() === Manager::RET_FINISH) { break; } $this->ocrConcat($char); $scanAt += $step; $this->logger->debug('Forward=%u', [$scanAt]); } } else { throw new \LogicException("OCR scan mode is exceptional."); } return $this->ocrComplete($this->result); }