Android-ElectricSheep-Automator
view release on metacpan or search on metacpan
lib/Android/ElectricSheep/Automator.pm view on Meta::CPAN
$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 ".'connect_device()'." before calling this."); return 1 }
my $w = $self->device_properties->get('w');
my $h = $self->device_properties->get('h');
my @fullspec;
for ('x1', 'y1', 'x2', 'y2', 'dt'){
if( ! exists($params->{$_}) || ! defined($params->{$_}) ){ last }
push @fullspec, $params->{$_};
}
my @cmd;
if( scalar(@fullspec) == 4 ){
if( ($params->{'x1'} < 0) || ($params->{'x1'} > $w) ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, input parameter 'x1' has a value (".$params->{'x1'}.") which is out of bounds."); return 1 }
if( ($params->{'y1'} < 0) || ($params->{'y1'} > $h) ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, input parameter 'y1' has a value (".$params->{'y1'}.") which is out of bounds."); return 1 }
if( ($params->{'x2'} < 0) || ($params->{'x2'} > $w) ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, input parameter 'x2' has a value (".$params->{'x2'}.") which is out of bounds."); return 1 }
if( ($params->{'y2'} < 0) || ($params->{'y2'} > $h) ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, input parameter 'y2' has a value (".$params->{'y2'}.") which is out of bounds."); return 1 }
@cmd = ('input', 'touchscreen', 'swipe', @fullspec);
} else {
# the time to do the move in milliseconds, there is a default of 100
# which is enough to swipe to next screen
my $dt = (exists($params->{'dt'}) && defined($params->{'dt'})) ? $params->{'dt'} : 100;
my $direction = (exists($params->{'direction'}) && defined($params->{'direction'})) ? $params->{'direction'} : undef;
if( ! defined $direction ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, input parameter 'direction' was not specified."); return 1 }
my ($x1, $y1, $x2, $y2);
if( ($direction =~ /^l(eft)?$/i) || ($direction =~ /^r(ight)?$/i) ){
# horizontal
$y1 = $y2 = int(3*$h/4);
} else {
# vertical
$x1 = $x2 = int($w/2);
}
if( ($direction =~ /^r(ight)?$/i) ){
$x1 = int(0.2*$w);
$x2 = $w - $x1;
}
if( ($direction =~ /^l(eft)?$/i) ){
$x2 = int(0.2*$w);
$x1 = $w - $x2;
}
if( ($direction =~ /^d(own)?$/i) ){
$y1 = int(0.2*$h);
$y2 = $h - $y1;
}
if( ($direction =~ /^u(p)?$/i) ){
$y2 = int(0.2*$h);
$y1 = $h - $y2;
}
@cmd = ('input', 'touchscreen', 'swipe', $x1, $y1, $x2, $y2, $dt);
}
# unfortunately Android::ADB uses IPC::Open2::open2() to run the adb shell command
# which does not capture STDERR, and so either they use open3 or we capture stderr thusly:
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 }
return 0; # success
}
# It finds all installed apps on device and appends with
# earlier results in $self->apps, and returns them as a hash
# keyed on appname. It also saves the returned hash into $self->apps
# optionally erasing previous entries (if 'make-fresh-apps-list'==1)
# The big question is whether to enquire the device for each package (app)
# installed and create an AppProperties object for each or not.
# The former is expensive and so you can do it on if-and-when-needed-basis
# (lazily). Or you can do it all at once here, it takes like 10-20 seconds.
# In any way, lazy or not, at the end the $self->apps HASH will be filled
# with the names of all packages installed on device (key).
# If 'lazy'==0, then for each installed app the device will be enquired
# and an AppProperties object will be created (it contains MainActivity,
# Permissions, etc.) and set as the value in the apps HASH.
# If 'packages' is specified and 'lazy'==0, then only those packages
# in 'packages' will be enquired, the $self->apps list will be
# refreshed with all the package names (key) but only some of them will
# contain an AppProperties object as the value, the other values
# will be undef.
# If no 'packages' was specified and 'lazy'==0, then all
# packages installed on device will be enquired and an AppProperties object
# will be associated with each of them in $self->apps.
# Default 'lazy' value is 1.
# Input:
# 'packages' => 'packagename' or regex (e.g. qr//) or [...] or { ...} :
# optionally specify a list of package names to find ONLY,
# default is to find ALL apps, which can be expensive if lazy>0
# the 'packages' items can be a scalar string for exact match
# or a compiled regex (qr//)
# 'force-reload-apps-list' => 0 or 1 : if 1, erase current list and start afresh
# 'lazy' => 1 or 0 : optionally specify not to enquire each package in detail,
# i.e. creating an AppProperties object for each package,
# but just add the package name as a key to the hash,
# leaving the value undef. This value will be
# created when needed, e.g. in an open_app() call.
# Default is to be lazy, 1.
# It needs that connect_device() to have been called prior to this call
#
# On failure it returns undef.
# On success it saves the results in $self->apps HASH and returns that.
#
# NOTE: enquiring installed apps entails this:
# 1. adb shell dumpsys package packages
# which is a general output of installed packages but does not contain
# activity information.
# 2. For a given installed app name (package) we enquire by
# adb shell dumpsys package com.example.myapp
# WARNING: the 2nd step if called for all the installed apps can take some
# time as it is done for each installed app.
# Perhaps a better approach is to lazily find apps by
# specifying the name of the app with the input parameter
# 'packages' => [...]
( run in 1.471 second using v1.01-cache-2.11-cpan-39bf76dae61 )