Android-ElectricSheep-Automator

 view release on metacpan or  search on metacpan

lib/Android/ElectricSheep/Automator/AppProperties.pm  view on Meta::CPAN

our $VERSION = '0.09';

use Mojo::Log;
use Config::JSON::Enhanced;
use XML::XPath;
use XML::LibXML;

use Data::Roundtrip qw/perl2dump no-unicode-escape-permanently/;

use overload ( '""'  => \&toString );

sub new {
	my $class = $_[0];
	my $params = $_[1] // {};

        my $parent = ( caller(1) )[3] || "N/A";
        my $whoami = ( caller(0) )[3];

	my $self = {
		'_private' => {
			'logger-object' => undef,
			'verbosity' => 0,
			'mother' => 0,
		},
		'data' => {
			# both are extracted from pkg=Package{3d33653 com.viber.voip}
			'packageName' => '',
			'packageId' => '',
			# where apks are
			'codePath' => '',
			# path(s) to one or more apk files found under the codePath above,
			# it can be empty []
			'apkPaths' => [],
			'resourcePath' => '',
			'applicationInfo' => '',
			'dataDir' => '',
			'versionCode' => '',
			'versionName' => '',
			'flags' => [],
			'privateFlags' => [],
			'pkgFlags' => [],
			'usesOptionalLibraries' => [],
			'usesLibraryFiles' => [],
			'timeStamp' => '',
			'firstInstallTime' => '',
			'lastUpdateTime' => '',
			'signatures' => '',
			'requestedPermissions' => [], # requested permissions
			'installPermissions' => [],
			'runtimePermissions' => [],
			'declaredPermissions' => [],
			'enabledComponents' => [],

			# activities
			# each item is a hash with name, fully qualified name etc.
			'MainActivity' => {}, # <<< this is an item as well if found
			'MainActivities' => [], # only those marked as .MAIN and .LAUNCHER
			'activities' => [], # all of them
		}
	};
	bless $self => $class;

	# we need a mother object (Android::ElectricSheep::Automator)
	if( (! exists $params->{'mother'})
	 || (! defined $params->{'mother'})
	 || (! defined $params->{'mother'}->adb())
	){ print STDERR "${whoami} (via $parent), line ".__LINE__." : error, input parameter 'mother' with our parent Android::ElectricSheep::Automator object was not specified.\n"; return undef }
	$self->{'_private'}->{'mother'} = $params->{'mother'};
	# we now have a mother
	my $mother = $self->mother();

	if( exists $params->{'logger-object'} ){
		$self->{'_private'}->{'logger-object'} = $params->{'logger-object'}
	} else { $self->{'_private'}->{'logger-object'} = $self->mother->log }
	# we now have a log
	my $log = $self->log;

	if( exists $params->{'verbosity'} ){
		$self->{'_private'}->{'verbosity'} = $params->{'verbosity'}
	} else { $self->{'_private'}->{'verbosity'} = $self->mother->verbosity }
	# we now have verbosity
	my $verbosity = $self->verbosity;

	# caller can specify some initial data to load
	# OR caller can specify a string which is the output of a dumpsys (for 1 package)
	# to parse it
	# else caller must run ->enquire() to enquire the real device at a later time
	if( exists $params->{'data'} ){
		my $d = $self->{'data'}; 
		my $p = $params->{'data'};
		for my $k (sort keys %$d){
			if( exists($p->{$k}) && defined($p->{$k}) ){
				if( $self->set($k, $p->{$k}) ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, call to ".'set()'." has failed for input parameter '$k', is its type as expected (".ref($d->{$k}).")?"); return undef }
			}
		}
	} elsif( exists $params->{'package'} ){
		# we have a package name, we will enquire about it and we
		# fill us up with its info
		if( 1 == $self->enquire({'package' => $params->{'package'}}) ){ $log->error("${whoami} (via $parent), line ".__LINE__." : error, failed to enquire package '".$params->{'package'}."' (call to ".'enquire()'." has failed)."); return undef }
	}

	my $packagename = $self->get('packageName');
	my $codepath = $self->get('codePath');
	# and now also find the package's apk dir (where its apks are)
	# we already have 'codePath'

	# adb shell pm path com.android.gallery2 will output:
	#   package:/product/app/Gallery2/Gallery2.apk
	# but there may be other apks there, so why not
	# adb shell ls "codePath"/*.apk
	#my @cmd = ('pm', 'path', $k);
	if( $verbosity > 0 ){ $log->info("${whoami} (via $parent), line ".__LINE__." : finding the APK files for app '$packagename' (code path: '$codepath' ...") }
	if( ! defined($codepath) || ($codepath=~/^\s*$/) ){ $log->warn("${whoami} (via $parent), line ".__LINE__." : warning, did not find any 'codePath' for app '".$self->get('packageName')."', no problem."); }
	else {
		# we have a codePath, perhaps we will find apks in there
		# but is it really a dir? it can be an apk (ending in apk)
		my $apkf = ($codepath =~ /\.apk$/i)
			? $codepath
			: File::Spec->catfile($codepath, '*.apk')
		;
		my @cmd = ('ls', '-al', $apkf);



( run in 0.834 second using v1.01-cache-2.11-cpan-39bf76dae61 )