Commit | Line | Data |
---|---|---|
9d265fd6 MG |
1 | package Android::ADB; |
2 | ||
3 | use 5.014000; | |
4 | use strict; | |
5 | use warnings; | |
6 | ||
7 | our $VERSION = '0.001'; | |
8 | ||
9 | use Android::ADB::Device; | |
10 | use Carp; | |
11 | use File::Slurp; | |
12 | use IPC::Open2; | |
13 | ||
14 | sub new { | |
15 | my ($class, %args) = @_; | |
16 | $args{path} //= $ENV{ADB}; | |
17 | $args{path} //= 'adb'; | |
18 | $args{args} //= []; | |
19 | bless \%args, $class | |
20 | } | |
21 | ||
22 | sub run { | |
23 | my ($self, @args) = @_; | |
24 | my ($out, $in); | |
25 | my @dev_args = $self->{device_serial} ? ('-s', $self->{device_serial}) : (); | |
26 | my $pid = open2 $out, $in, $self->{path}, @{$self->{args}}, @args; | |
27 | my $result = read_file $out; | |
28 | close $out; | |
29 | close $in; | |
30 | waitpid $pid, 0 or croak "$!"; | |
31 | $result; | |
32 | } | |
33 | ||
34 | sub start_server { shift->run('start-server') } | |
35 | sub kill_server { shift->run('kill-server') } | |
36 | ||
37 | sub connect { shift->run('connect', @_) } | |
38 | sub disconnect { shift->run('disconnect', @_) } | |
39 | ||
40 | sub devices { | |
41 | my @devices = split '\n', shift->run('devices', '-l'); | |
42 | my @result; | |
43 | for (@devices) { | |
44 | next if /^List of devices/; | |
45 | next unless / /; | |
46 | push @result, Android::ADB::Device->new(split) | |
47 | } | |
48 | @result | |
49 | } | |
50 | ||
51 | sub set_device { | |
52 | my ($self, $device) = @_; | |
53 | $self->{device_serial} = $device->serial; | |
54 | } | |
55 | ||
56 | sub wait_for_device { shift->run('wait-for-device') } | |
57 | sub get_state { shift->run('get-state') } | |
58 | sub get_serialno { shift->run('get-serialno') } | |
59 | sub get_devpath { shift->run('get-devpath') } | |
60 | sub remount { shift->run('remount') } | |
61 | sub reboot { shift->run('reboot', @_) } | |
62 | sub reboot_bootloader { shift->run('reboot-bootloader') } | |
63 | sub root { shift->run('root') } | |
64 | sub usb { shift->run('usb') } | |
65 | sub tcpip { shift->run('tcpip', @_) } | |
66 | ||
67 | sub push { | |
68 | my ($self, $local, $remote) = @_; | |
69 | $self->run(push => $local, $remote) | |
70 | } | |
71 | ||
72 | sub pull { | |
73 | my ($self, $remote, $local) = @_; | |
74 | $self->run(push => $remote, $local) | |
75 | } | |
76 | ||
77 | sub pull_archive { | |
78 | my ($self, $remote, $local) = @_; | |
79 | $self->run(push => '-a', $remote, $local) | |
80 | } | |
81 | ||
82 | sub shell { shift->run(shell => @_) } | |
83 | ||
84 | 1; | |
85 | __END__ | |
86 | ||
87 | =encoding utf-8 | |
88 | ||
89 | =head1 NAME | |
90 | ||
91 | Android::ADB - thin wrapper over the 'adb' command | |
92 | ||
93 | =head1 SYNOPSIS | |
94 | ||
95 | use Android::ADB;; | |
96 | my $adb = Android::ADB->new(path => '/opt/android/platform-tools/adb'); | |
97 | my @devices = $adb->devices; | |
98 | $adb->set_device($devices[0]); | |
99 | $adb->push('file.txt', '/sdcard/'); | |
100 | sleep 10; | |
101 | $adb->reboot('recovery'); | |
102 | ||
103 | =head1 DESCRIPTION | |
104 | ||
105 | This module is a minimal wrapper over the Android Debug Bridge | |
106 | (C<adb>) command for manipulating Android devices. | |
107 | ||
108 | Methods die on non-zero exit code and return the text printed by the | |
109 | C<adb> command. The available methods are: | |
110 | ||
111 | =over | |
112 | ||
113 | =item Android::ADB->B<new>([I<args>]) | |
114 | ||
115 | Create a new Android::ADB object. The available arguments are C<path>, | |
116 | the path to the C<adb> executable (defaults to the value of the | |
117 | environment variable C<ADB> or the string C<adb>) and C<args>, an | |
118 | arrayref of arguments passed to every adb command (defaults to []). | |
119 | ||
120 | =item $adb->B<devices> | |
121 | ||
122 | Returns a list of L<Android::ADB::Device> objects representing | |
123 | connected devices. | |
124 | ||
125 | =item $adb->B<set_device>(I<$device>) | |
126 | ||
127 | Takes an L<Android::ADB::Device> and directs all further commands to | |
128 | that device by passing C<-s serialno> to every command. | |
129 | ||
130 | =item $adb->B<run>(I<$command>, [I<@args>]) | |
131 | ||
132 | Run an arbitrary ADB command and return its output. | |
133 | ||
134 | =item $adb->B<start_server> | |
135 | ||
136 | =item $adb->B<kill_server> | |
137 | ||
138 | =item $adb->B<connect>(I<$host_and_port>) | |
139 | ||
140 | =item $adb->B<disconnect>([I<$host_and_port>]) | |
141 | ||
142 | =item $adb->B<wait_for_device> | |
143 | ||
144 | =item $adb->B<get_state> | |
145 | ||
146 | =item $adb->B<get_serialno> | |
147 | ||
148 | =item $adb->B<get_devpath> | |
149 | ||
150 | =item $adb->B<remount> | |
151 | ||
152 | =item $adb->B<reboot>([I<$where>]) | |
153 | ||
154 | =item $adb->B<reboot_bootloader> | |
155 | ||
156 | =item $adb->B<root> | |
157 | ||
158 | =item $adb->B<usb> | |
159 | ||
160 | =item $adb->B<tcpip>(I<$port>) | |
161 | ||
162 | =item $adb->B<push>(I<$local>, I<$remote>) | |
163 | ||
164 | =item $adb->B<pull>(I<$remote>, I<$local>) | |
165 | ||
166 | =item $adb->B<shell>(I<@args>) | |
167 | ||
168 | Analogues of the respective adb commands. | |
169 | ||
170 | =item $adb->B<pull_archive>(I<$remote>, I<$local>) | |
171 | ||
172 | Same as C<adb pull -a $remote $local>. | |
173 | ||
174 | =back | |
175 | ||
176 | =head1 AUTHOR | |
177 | ||
178 | Marius Gavrilescu, E<lt>marius@ieval.roE<gt> | |
179 | ||
180 | =head1 COPYRIGHT AND LICENSE | |
181 | ||
182 | Copyright (C) 2017 by Marius Gavrilescu | |
183 | ||
184 | This library is free software; you can redistribute it and/or modify | |
185 | it under the same terms as Perl itself, either Perl version 5.24.2 or, | |
186 | at your option, any later version of Perl 5 you may have available. | |
187 | ||
188 | ||
189 | =cut |