Android-ElectricSheep-Automator
view release on metacpan or search on metacpan
lib/Android/ElectricSheep/Automator/ADB.pm view on Meta::CPAN
package Android::ElectricSheep::Automator::ADB;
use 5.014000;
use strict;
use warnings;
our $VERSION = '0.009';
use Android::ElectricSheep::Automator::ADB::Device;
use Carp;
use File::Slurp;
use IPC::Open2;
# we already have a run() 'method'
# which clashes with IPC::Run's run() sub
# fingers crossed: don't import IPC::Run::run()
# and use fully qualified name when calling it.
use IPC::Run qw/timeout/;
sub new {
my ($class, %args) = @_;
$args{path} //= $ENV{ADB};
$args{path} //= 'adb';
$args{verbosity} //= 0;
$args{args} //= [];
bless \%args, $class
}
sub run2 {
my ($self, @args) = @_;
my ($out, $in);
my @dev_args = $self->{device_serial} ? ('-s', $self->{device_serial}) : ();
my $pid = open2 $out, $in, $self->{path}, @{$self->{args}}, @args;
my $result = read_file $out;
close $out;
close $in;
waitpid $pid, 0 or croak "$!";
$result;
}
# returns an arrayref of
# [statuscode, stdout, stderr]
# on success statuscode is 0 and stdout/stderr may or may not have something
# on failure statuscode is 1 and stdout/stderr may or may not have something
# the '$result' returned by original run2() is now the stdout,
# the 2nd item in the returned arrayref
sub run {
my ($self, @args) = @_;
my ($out, $in, $err);
my @dev_args = $self->{device_serial} ? ('-s', $self->{device_serial}) : ();
my @cmd = ($self->{path}, @{$self->{args}}, @args);
if( $self->{verbosity} > 0 ){ print STDOUT __PACKAGE__.'::run()'." : executing command : ".join(' ', @cmd)."\n" }
# check if undef is passed in @cmd, IPC does not like that
for (@cmd){
if( ! defined $_ ){
my $errstr = __PACKAGE__.'::run()'." : error, command contains undef values (Perl's undef) which is not allowed, most likely a cockup with creating the command array: @cmd";
carp $errstr;
return [1, "", $errstr]
}
}
my $res = eval {
IPC::Run::run(
\@cmd,
\$in, \$out, \$err,
# AHP: on timeout it throws an exception matching
# /^IPC::Run: .*timed out/
# or specify your own exception name (see doc)
# I can't find what unit the timeout interval is!
IPC::Run::timeout(1000)
)
};
# WARNING: adb on error sometimes returns non-zero exit code
# but sometimes it exits normally with zero but there is
# an error which you can find in the STDOUT/STDERR.
# Unfortunately this is not a consistent message.
# For example:
# adb shell xyz
# will set $? to 127
# but, e.g. this:
# adb shell input keycombination 1 2
# will exit with $?=0 and print some error message!
# Searching for 'Error:' in STDERR is ok?
# TODO: this needs to be dealt with here.
my $exit_code = $? >> 8;
#if( (! $res) || $@ || ($err=~/\bError\: /) ){
if( ($exit_code > 0) || $@ || ($err=~/\bError\: /) ){
( run in 1.253 second using v1.01-cache-2.11-cpan-39bf76dae61 )