Android-ElectricSheep-Automator
view release on metacpan or search on metacpan
lib/Android/ElectricSheep/Automator.pm view on Meta::CPAN
my $parent = ( caller(1) )[3] || "N/A";
my $whoami = ( caller(0) )[3];
my $log = $self->log();
my $verbosity = $self->verbosity;
if( ! $self->is_device_connected() ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, you need to connect a device to the desktop and ALSO explicitly call ".'device_connected()'." before calling this."); return undef }
my $filename = exists($params->{'filename'}) && defined($params->{'filename'}) ? $params->{'filename'} : undef;
my $FH;
if( ! defined $filename ){
($FH, $filename) = tempfile(CLEANUP=>$self->cleanup);
close $FH;
}
# optional display-id (TODO: confirm that this display id is valid with
# dumpsys SurfaceFlinger --display-id
my @options;
if( exists($params->{'display-id'}) && defined($params->{'display-id'}) ){
push @options, '--display-id', $params->{'display-id'}
}
# WARNING, you need to wake up the phone before dumping !!!!
my $devicefile = File::Spec->catfile('/', 'data', 'local', 'tmp', $$.'.png');
my @cmd = ('screencap', @options, '-p', $devicefile);
if( $verbosity > 0 ){ $log->info("${whoami} (via $parent), line ".__LINE__." : sending command to adb: @cmd") }
my $res = $self->adb->shell(@cmd);
if( ! defined $res ){ $log->error(join(" ", @cmd)."\n${whoami} (via $parent), line ".__LINE__." : error, above shell command has failed, got undefined result, most likely shell command did not run at all, this should not be happening."); return unde...
if( $res->[0] != 0 ){ $log->error(join(" ", @cmd)."\n${whoami} (via $parent), line ".__LINE__." : error, above shell command has failed, with:\nSTDOUT:\n".$res->[1]."\n\nSTDERR:\n".$res->[2]."\nEND."); return undef }
$res = $self->adb->pull($devicefile, $filename);
if( ! defined $res ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, failed to pull remote file '$devicefile' into local file '$filename', because undefined was returned, this should not be happening."); return undef }
if( $res->[0] != 0 ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, failed to pull remote file '$devicefile' into local file '$filename' with:\nSTDOUT:\n".$res->[1]."\n\nSTDERR:\n".$res->[2]."\nEND."); return undef }
@cmd = ("rm", "-f", $devicefile);
if( $verbosity > 0 ){ $log->info("${whoami} (via $parent), line ".__LINE__." : sending command to adb: @cmd") }
$res = $self->adb->shell(@cmd);
if( ! defined $res ){ $log->error(join(" ", @cmd)."\n${whoami} (via $parent), line ".__LINE__." : error, above shell command has failed, got undefined result, most likely shell command did not run at all, this should not be happening."); return unde...
if( $res->[0] != 0 ){ $log->error(join(" ", @cmd)."\n${whoami} (via $parent), line ".__LINE__." : error, above shell command has failed, with:\nSTDOUT:\n".$res->[1]."\n\nSTDERR:\n".$res->[2]."\nEND."); return undef }
# let's return the string content back, no we return back an Image::PNG
#my $contents;
#if( ! open($FH, '<', $filename) ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, failed to open file with dump for reading '$filename', $!"); return undef }
#{ local $/ = undef; $contents = <$FH> } close $FH;
# create an Image::PNG to return back
my $img = Image::PNG->new();
if( ! defined $img ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, call to ".'Image::PNG->new()'." has failed."); return undef }
if( ! $img->read($filename) ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, failed to read local file '$filename' as PNG (call to ".'Image::PNG->read()'." has failed)."); return undef }
return $img;
}
# It takes a video recording of current screen on device and
# saves its to the specified file ($filename).
# Optionally specify 'time-limit' or a default of 10s is used.
# Optionally specify 'bit-rate'.
# Optionally specify %size = ('width' => ..., 'height' => ...)
# Optionally specify if $bugreport==1, then Android will overlay debug info on movie.
# Optionally specify 'display-id'.
# Output format of recording is MP4.
# It returns 1 on failure, 0 on success.
# it needs that connect_device() to have been called prior to this call
sub dump_current_screen_video {
my ($self, $params) = @_;
my $parent = ( caller(1) )[3] || "N/A";
my $whoami = ( caller(0) )[3];
my $log = $self->log();
my $verbosity = $self->verbosity;
if( ! $self->is_device_connected() ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, you need to connect a device to the desktop and ALSO explicitly call ".'device_connected()'." before calling this."); return 1 }
my $filename = exists($params->{'filename'}) && defined($params->{'filename'}) ? $params->{'filename'} : undef;
if( ! defined $filename ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, input parameter 'filename' is not specified, an output filename must be specified."); return 1 }
my @options;
# optional duration or default of 10 seconds. (Android default is 180 which is stupidly huge for us)
if( exists($params->{'time-limit'}) && defined($params->{'time-limit'}) ){
push @options, '--time-limit', $params->{'time-limit'}
} else { push @options, '--time-limit', '10' }
# optional bitrate (don't know what Android default is)
if( exists($params->{'bit-rate'}) && defined($params->{'bit-rate'}) ){
push @options, '--bit-rate', $params->{'bit-rate'}
}
# optional bugreport (Android overlays timestamp etc.)
if( exists($params->{'bugreport'}) && defined($params->{'bugreport'})
&& ($params->{'bugreport'} > 0)
){
push @options, '--bugreport'
}
# optional size
if( exists($params->{'size'}) && defined($params->{'size'}) ){
if( (ref($params->{'size'}) ne 'HASH')
|| (! exists $$params->{'size'}->{'width'})
|| (! defined $$params->{'size'}->{'width'})
|| (! exists $$params->{'size'}->{'height'})
|| (! defined $$params->{'size'}->{'height'}) ){ $log->info("${whoami} (via $parent), line ".__LINE__." : error, specified parameter 'size' is either not a HASHref or it does not contain the two required keys 'width' and 'height'."); return 1 }
push @options, '--size', $params->{'size'}->{'width'}, $params->{'size'}->{'height'}
}
# optional display-id (TODO: confirm that this display id is valid with
# dumpsys SurfaceFlinger --display-id
if( exists($params->{'display-id'}) && defined($params->{'display-id'}) ){
push @options, '--display-id', $params->{'display-id'}
}
# WARNING, you need to wake up the phone before dumping !!!!
my $devicefile = File::Spec->catfile('/', 'data', 'local', 'tmp', $$.'.mp4');
my @cmd = ('screenrecord', @options, $devicefile);
if( $verbosity > 0 ){ $log->info("${whoami} (via $parent), line ".__LINE__." : sending command to adb: @cmd") }
my $res = $self->adb->shell(@cmd);
if( ! defined $res ){ $log->error(join(" ", @cmd)."\n${whoami} (via $parent), line ".__LINE__." : error, above shell command has failed, got undefined result, most likely shell command did not run at all, this should not be happening."); return 1 }
if( $res->[0] != 0 ){ $log->error(join(" ", @cmd)."\n${whoami} (via $parent), line ".__LINE__." : error, above shell command has failed, with:\nSTDOUT:\n".$res->[1]."\n\nSTDERR:\n".$res->[2]."\nEND."); return 1 }
$res = $self->adb->pull($devicefile, $filename);
if( ! defined $res ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, failed to pull remote file '$devicefile' into local file '$filename', because undefined was returned, this should not be happening."); return 1 }
if( $res->[0] != 0 ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, failed to pull remote file '$devicefile' into local file '$filename' with:\nSTDOUT:\n".$res->[1]."\n\nSTDERR:\n".$res->[2]."\nEND."); return 1 }
@cmd = ("rm", "-f", $devicefile);
if( $verbosity > 0 ){ $log->info("${whoami} (via $parent), line ".__LINE__." : sending command to adb: @cmd") }
$res = $self->adb->shell(@cmd);
if( ! defined $res ){ $log->error(join(" ", @cmd)."\n${whoami} (via $parent), line ".__LINE__." : error, above shell command has failed, got undefined result, most likely shell command did not run at all, this should not be happening."); return 1 }
if( $res->[0] != 0 ){ $log->error(join(" ", @cmd)."\n${whoami} (via $parent), line ".__LINE__." : error, above shell command has failed, with:\nSTDOUT:\n".$res->[1]."\n\nSTDERR:\n".$res->[2]."\nEND."); return 1 }
# let's return the string content back, no we return back 1 or 0, output must be saved to file
#my $contents;
#if( ! open($FH, '<', $filename) ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, failed to open file with dump for reading '$filename', $!"); return 1 }
#{ local $/ = undef; $contents = <$FH> } close $FH;
return 0; # success
}
# returns 1 on failure, 0 on success
# it needs that connect_device() to have been called prior to this call
sub wake_up {
my ($self, $params) = @_;
$params //= {};
my $parent = ( caller(1) )[3] || "N/A";
my $whoami = ( caller(0) )[3];
my $log = $self->log();
my $verbosity = $self->verbosity();
lib/Android/ElectricSheep/Automator.pm view on Meta::CPAN
C<$params> is a HASH_REF which may or should contain:
=over 4
=item * B<C<filename>>
optionally save the returned XML string to the specified file.
=back
It returns C<undef> on failure or the UI XML dump, as a string, on success.
=head2 B<C<dump_current_screen_shot($params)>>
It dumps the current screen as a PNG image and returns that as
a L<Image::PNG> object, optionally saving it to the specified file.
C<$params> is a HASH_REF which may or should contain:
=over 4
=item * B<C<filename>>
optionally save the returned XML string to the specified file.
=back
It returns C<undef> on failure or a L<Image::PNG> image, on success.
=head2 B<C<dump_current_screen_video($params)>>
It dumps the current screen as MP4 video and saves that
in specified file.
C<$params> is a HASH_REF which may or should contain:
=over 4
=item * B<C<filename>>
save the recorded video to the specified file in MP4 format. This
is required.
=item * B<C<time-limit>>
optionally specify the duration of the recorded video, in seconds. Default is 10 seconds.
=item * B<C<bit-rate>>
optionally specify the bit rate of the recorded video in bits per second. Default is 20Mbps.
=item * B<C<size>>
optionally specify the size (geometry) of the recorded video as a
HASH_REF with keys C<width> and C<height>, in pixels. Default is "I<the
device's main display resolution>".
=item * B<C<bugreport>>
optionally set this flag to 1 to have Android overlay debug information
on the recorded video, e.g. timestamp.
=item * B<C<display-id>>
for a device set up with multiple physical displays, optionally
specify which one to record -- if not the main display -- by providing the
display id. You can find display ids with L</list_physical_displays()>
or, from the CLI, by C<adb shell dumpsys SurfaceFlinger --display-id>
=back
C<adb shell screenrecord --help> contains some more documentation.
=head2 B<C<list_physical_displays()>>
It lists the IDs of all the physical displays connected to the
device, including the main one and returns these back as a HASH_REF
keyed on display ID. It needs that connect_device() to have been called prior to this call
It returns C<undef> on failure or the results as a HASH_REF keyed on display ID.
=head2 B<C<list_running_processes($params)>>
It finds the running processes on device (using a `ps`),
optionally can save the (parsed) `ps`
results as JSON to the specified 'filename'.
It returns C<undef> on failure or the results as a hash of hashes on success.
C<$params> is a HASH_REF which may or should contain:
=over 4
=item * B<C<extra-fields>>
optionally add more fields (columns) to the report by C<ps>, as an ARRAY_REF.
For example, C<['TTY','TIME']>.
=back
It needs that connect_device() to have been called prior to this call
It returns C<undef> on failure or a hash with these keys on success:
=over 4
=item * B<C<raw>> : contains the raw `ps` output as a string.
=item * B<C<perl>> : contains the parsed raw output as a Perl hash with
each item corresponding to one process, keyed on process command and arguments
(as reported by C<ps>, verbatim), as a hash keyed on each field (column)
of the C<ps> output.
=item * B<C<json>> : the above data converted into a JSON string.
=back
=head2 B<C<pidof($params)>>
It returns the PID of the specified command name.
The specified command name must match the app or command
( run in 0.565 second using v1.01-cache-2.11-cpan-7fcb06a456a )