2 package PerlACE
::TestTarget_Android
;
4 # ******************************************************************
5 # Description : Creates a PerlACE::Android
7 # Create Date : 29/20/2008
8 # ******************************************************************
10 # ******************************************************************
12 # ******************************************************************
16 use PerlACE
::TestTarget
;
17 use PerlACE
::ProcessVX
;
25 use POSIX
"sys_wait_h";
26 require PerlACE
::ProcessAndroid
;
28 our @ISA = qw(PerlACE::TestTarget);
30 $PerlACE::TestTarget_Android
::EMULATOR_RUNNING
= 0;
31 $PerlACE::TestTarget_Android
::LIBS
= ();
36 my $config_name = shift;
37 my $component = shift;
39 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
40 print STDERR
"New Android target: $config_name : $component\n";
43 my $class = ref ($proto) || $proto;
45 bless ($self, $class);
47 $self->GetConfigSettings($config_name);
48 $self->{FSROOT
} = $ENV{'ANDROID_FS_ROOT'};
49 $self->{PROCESS
} = undef;
53 if ($PerlACE::TestTarget_Android
::EMULATOR_RUNNING
== 0) {
54 $self->start_target ();
63 if ($self->{RUNNING
} == 1) {
64 # kill the emulator. No need to shutdown gracefully.
65 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
66 print STDERR
"Killing the Android emulator\n";
68 $self->KillAll ('emulator*');
69 $self->KillAll ('adb');
70 $PerlACE::TestTarget_Android
::EMULATOR_RUNNING
= 0;
71 $PerlACE::TestTarget_Android
::LIBS
= ();
75 # ******************************************************************
77 # ******************************************************************
84 my $newfile = $self->{FSROOT
} . "/" . $file;
85 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
86 print STDERR
"Android LocalFile for $file is $newfile\n";
97 # If we have -Config ARCH, use the -ExeSubDir setting as a sub-directory
98 # of the lib path. This is in addition to the regular LibPath.
99 if (!$noarch && defined $self->{ARCH
}) {
100 $self->AddLibPath($dir, 1);
101 $dir .= '/' . $self->{EXE_SUBDIR
};
104 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
105 print STDERR
"Adding libpath $dir\n";
107 $self->{LIBPATH
} = PerlACE
::concat_path
($self->{LIBPATH
}, $dir);
113 my $process = new PerlACE
::ProcessAndroid
($self, @_);
120 $self->{REBOOT_NEEDED
} = 1;
127 $self->{REBOOT_NEEDED
} = undef;
128 print STDERR
"Attempting to reboot target...\n";
134 # For now, we're assuming one target (avd) is running in the test environment.
135 # Need to change this when more than one avd's need to start
139 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
140 $silent = "2> /dev/null"
143 if (! defined ($ENV{'ANDROID_SDK_ROOT'})) {
144 print STDERR
"Error: Android SDK root not defined.\n";
147 if (! defined ($ENV{'ANDROID_AVD_NAME'})) {
148 print STDERR
"Error: Android AVD name not defined.\n";
151 my $avd_name = $ENV{'ANDROID_AVD_NAME'};
152 my $android_process = $ENV{'ANDROID_SDK_ROOT'} . "/tools/android";
153 my $avd_process = $ENV{'ANDROID_SDK_ROOT'} . "/tools/emulator";
154 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
155 my $user_data_image = $ENV{'ANDROID_SDK_HOME'} . "/.android/avd/" . $avd_name . ".avd/userdata-qemu.img";
157 my $avd_options = "-noaudio -no-window -wipe-data";
159 if (defined ($ENV{'ANDROID_AVD_OPTIONS'})) {
160 print STDERR
"Resetting AVD options\n";
161 $avd_options = $ENV{'ANDROID_AVD_OPTIONS'};
164 $self->KillAll ("emulator*");
167 if ($self->{PROCESS
} = fork) {
171 elsif (defined $self->{PROCESS
}) {
173 my $user_image_cmd = "rm -f " . $user_data_image;
174 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
175 print STDERR
"Removing user data image: $user_image_cmd\n";
178 system ( $user_image_cmd );
180 print STDERR
"failed to execute: $!\n";
183 my $avd_cmd = "$avd_process" .' -avd ' . "$avd_name $avd_options";
184 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
185 print STDERR
"Starting emulator cmd: $avd_cmd\n";
190 print STDERR
"failed to execute: $!\n";
194 elsif ($! =~ /No more process/) {
195 #EAGAIN, supposedly recoverable fork error
201 print STDERR
"ERROR: Can't fork <" . $avd_process . ">: $!\n";
206 my $timeout = $self->AdbWaitForDeviceTimeout ();
208 local $SIG{ALRM
} = sub { die "alarm\n" }; # NB: \n required
210 # start the waiting...
211 my $wait_cmd = $adb_process . ' wait-for-device';
212 system ( $wait_cmd );
219 exit unless $@
eq "alarm\n"; # propagate unexpected errors
222 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
223 print STDERR
"Emulator is running <$self->{PROCESS}> -> start the tests.\n";
228 # AVD is up and running and ready to spawn executables.
229 # First some preparation.
230 my $cmd = $adb_process . ' shell "mkdir ' . $self->{FSROOT
} . '/tmp "' . $silent;
231 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
232 print STDERR
"Start to execute : $cmd\n";
236 $self->{RUNNING
} = 1;
237 $PerlACE::TestTarget_Android
::EMULATOR_RUNNING
= 1;
241 sub WaitForFileTimed
($)
248 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
249 $silent = ' > /dev/null 2>&1';
252 if ($PerlACE::Process
::WAIT_DELAY_FACTOR
> 0) {
253 $timeout *= $PerlACE::Process
::WAIT_DELAY_FACTOR
;
256 my $newfile = $self->LocalFile ($file);
257 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
258 print STDERR
"Android waits $timeout seconds for $newfile\n";
261 # Since the file is available on the target (which we cannot reach),
262 # we will try to pull the file from the target to a local directory.
263 # If succeed, the the file is there an we can continue.
264 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
265 my $fsroot_target = $self->{FSROOT
};
267 my $cmd_copy_ior = $adb_process . ' pull ' . $newfile . ' ' .
268 File
::Spec
->tmpdir() . '/' .
269 basename
($newfile) . $silent;
271 while ($timeout-- != 0) {
272 # copy the ior back to the host sytem
273 if (system ( $cmd_copy_ior ) == 0) {
274 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
275 print STDERR
"Pull $newfile succeeded\n";
288 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
291 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
292 $silent = ' > /dev/null 2>&1';
295 my $targetfile = $self->LocalFile ($file);
296 my $cmd = "$adb_process" . ' shell rm '. "$targetfile" . $silent;
298 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
299 print STDERR
"DeleteFile cmd: $cmd\n";
313 if ($self->{RUNNING
} == 1) {
314 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
315 print STDERR
"Killing emulator process <$self->{PROCESS}>\n";
318 my $cnt = kill (1, $self->{PROCESS
});
320 waitpid ($self->{PROCESS
}, WNOHANG
);
321 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
322 print STDERR
"Killed $cnt process(es)\n";
324 # $self->check_return_value ($?);
327 $self->{RUNNING
} = 0;
333 my $procmask = shift;
334 if ($OSNAME eq 'MSWin32') {
335 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
336 print STDERR
"Killall not implemented for Windows\n";
341 my $cmd_killall = "killall -q -r $procmask";
342 system ( $cmd_killall );
352 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
353 $silent = "2> /dev/null"
356 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
358 my $targetfile = $self->LocalFile ($src);
359 my $cmd = "$adb_process" . ' push '. "\"$src\" \"$targetfile\" $silent";
361 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
362 print STDERR
"PutFile cmd: $cmd\n";
375 my $remote_file = shift;
376 my $local_file = shift;
379 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
380 $silent = "2> /dev/null"
383 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
385 if (!defined $local_file) {
386 $local_file = $remote_file;
388 $remote_file = $self->LocalFile($remote_file);
389 my $cmd = "$adb_process" . ' pull '. "$remote_file $local_file $silent";
391 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
392 print STDERR
"GetFile cmd: $cmd\n";
409 if (!defined $ENV{'ACE_TEST_VERBOSE'}) {
410 $silent = "2> /dev/null"
413 foreach my $lib (@
{$PerlACE::TestTarget_Android
::LIBS
}) {
414 if ($lib eq $newlib) {
415 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
416 print STDERR
"Duplicate lib $newlib\n";
422 my $adb_process = $ENV{'ANDROID_SDK_ROOT'} . "/platform-tools/adb";
424 my $cmd = "$adb_process" . ' push '. "\"$newlib\" \"$tgtlib\" $silent";
426 if (defined $ENV{'ACE_TEST_VERBOSE'}) {
427 print STDERR
"PutLib cmd: $cmd\n";
435 # keep tabs on copied libs
436 push(@
{$PerlACE::TestTarget_Android
::LIBS
}, $newlib);