Break On Through To the Other Side
adb_
>
http://eyal.fr
Eyal Lezmy
Join us!
bit.ly/adb-chill
Slides
>
How adb works
Some adb commands
The internals
Dev on the adb project
The Android dev tools
>
>
>
>
>
alias adb=“Android Debug Bridge”
A command line tool
To communicate with Android devices
physical or emulators
Part of the SDK
on the platform-tools directory
2 versions distributed
Stable & Preview channel
How adb
works
adb
daemon
adb
client
adb
server
adb
client
adb
client
adb_
>
adb
client
adb
daemon
adb
daemon
Started at boot
As background process
Executes commands
on the device
adb
daemon
adb
server
adb
daemon
adb
client
adb
server
adb
daemon
adb
client
adb
server
A practical case
adb
client
adb
client
Is there an ADB Server?
adb
client
adb
server
Start adb server
adb
client
adb
server
Port 5037
adb
client
adb
server
Scan for Android devices and emulators
adb
client
adb
server
localhost
5555
5557
5681
adb
client
adb
server
localhost
5555
5557
5681
Is there a device bound here?
adb
client
adb
server
localhost
5555
5557
5681
Is there a device bound here?
adb
client
adb
server
localhost
5555
5557
5681
Is there a device bound here?
adb
client
adb
server
localhost
adb
daemon
5557
Android Studio
Emulator
adb
client
adb
server
localhost
adb
daemon
5557
Android Studio
Emulator
Open a connection to the device
adb
client
adb
server
USB Interface
adb
client
adb
server
USB Interface
/dev/…
adb
daemon
Nexus 6P (USB)
adb
client
adb
server
adb
daemon
Nexus 6P
adb
daemon
Network device
adb
daemon
AS Emulator
adb
client
adb
server
adb
daemon
Nexus 6P
adb
daemon
Network device
adb
daemon
AS Emulator
Some adb commands
adb tcpip 5555
>
Enable wireless debugging
adb connect <device-ip>
>
adb usb
>
Disable wireless debugging
adb tcpip 5555
>
adb tcpip 5555
>
ADB Server asks the Daemon to enable the network connection
“tcpip:5555”
adb tcpip 5555
>
ADB Server asks the Daemon to enable the network connection
The daemon sets a system property
setprop service.adb.tcp.port 5555
adb tcpip 5555
>
ADB Server asks the Daemon to enable the network connection
The daemon sets a system property
ADB Daemon closes itself
exit(1)
adb tcpip 5555
>
ADB Server asks the Daemon to enable the network connection
The daemon sets a system property
ADB Daemon closes itself
The system restarts automatically ADB Daemon
service adbd /sbin/adbd
adb tcpip 5555
>
ADB Server asks the Daemon to enable the network connection
The daemon sets a system property
ADB Daemon closes itself
The system restarts automatically ADB Daemon
The Daemon will read the property at start and will listen to this port
getprop service.adb.tcp.port
adb tcpip 5555
>
setprop service.adb.tcp.port 5555
#
stop adbd
#
start adbd
#
adb tcpip 5555
>
setprop persist.adb.tcp.port 5555
#
stop adbd
#
start adbd
#
Remains after reboot
adb devices -l
>
192.168.63.101:5555 device product:vbox86p model:myGenymotionNexus5 device:vbox86p
F5AZFG013292 device usb:336592896X product:WW_Z00A model:ASUS_Z00AD device:Z00A
HT4CNJT00728 device usb:336592896X product:volantis model:Nexus_9 device:flounder
Detailed device list
adb -e shell
>
Filter the type of device
Emulator or network device
adb -d shell
>
USB device
adb -H <ip> -P <port> devices
>
Access a remote ADB Server
adb -H 10.5.0.5 -P 5037 devices
>
adb
client
adb -H 10.5.0.5 -P 5037 devices
>
adb
client
adb
server
5037
adb -H 10.5.0.5 -P 5037 devices
>
Device farm server
10.5.0.5
adb
client
adb
server
Samsung S6
Genymotion Kitkat
Pixel 2 XL
5037
adb -H 10.5.0.5 -P 5037 devices
>
Device farm server
10.5.0.5
adb reverse
>
adb reverse
>
Backend Server
Your app
localhost
localhost
2323
8181
adb reverse tcp:2323 tcp:8181
>
Backend Server
Your app
localhost
localhost
2323
8181
adb reverse tcp:2323 tcp:8181
>
Backend Server
Your app
localhost
localhost
2323
8181
adb reverse
>
SecuredBackend Server
Your app
VPN
adb reverse
>
SecuredBackend Server
Your app
VPN
Proxy
Proxy
Setting
adb shell settings put global http_proxy localhost:3333
>
adb reverse tcp:3333 tcp:3128
>
docker run --name squid \
--publish 127.0.0.1:3128:3128 \
--volume $HOME/squid.conf:/etc/squid3/squid.conf \
--volume /tmp/squid/cache:/var/spool/squid3 \
--volume /tmp/squid/cache:/var/log/squid3 \
sameersbn/squid:3.3.8-12
>
adb
>
adb
>
...
-p <name or path> - simple product name like 'sooner', or a
relative/absolute path to a product out
directory like 'out/target/product/sooner'.
If -p is not specified, the
ANDROID_PRODUCT_OUT environment variable is
used, which must be an absolute path.
adb
>
...
-p <name or path> - simple product name like 'sooner', or a
relative/absolute path to a product out
directory like 'out/target/product/sooner'.
If -p is not specified, the
ANDROID_PRODUCT_OUT environment variable is
used, which must be an absolute path.
Sooner??
Andy Rubin
Holy crap, I guess we’re not going to ship that phone.
”
“
The adb internals
adb
daemon
adb
client
adb
server
adb
daemon
adb
client
adb
server
C-S
S-D
Client-Server
adb shell ls
>
adb shell ls
>
adb
client
adb
server
adb shell ls
>
adb
client
adb
server
What’s your protocol version?
adb
client
adb
server
adb shell ls
>
What’s your protocol version?
host:version
adb
client
adb
server
adb shell ls
>
It’s version 36
host:version
OKAY 36
adb
client
adb
server
adb shell ls
>
host:version
OKAY 36
adb
client
adb
server
adb shell ls
>
host:transport-any
I want to talk to any kind of device
adb
client
adb
server
adb shell ls
>
host:transport-any
OKAY
OKAY!
adb
client
adb
server
adb shell ls
>
shell:ls
Please execute the shell service with the parameter “ls”
adb
client
adb
server
adb shell ls
>
shell:ls
“ls output”
cache
charge
config
...
adb
client
adb
server
adb shell ls
>
host:version
OKAY 36
host:transport-any
OKAY
shell:ls
“ls output”
Service
execution
Startup
Device selection
adb devices
>
adb server version (32) doesn't match this client (36); killing…
adb devices
>
adb server is out of date. killing...
adb
>
At device selection
host:transport-any
adb
>
adb -s <serial>
>
At device selection
adb -d
>
adb -e
>
host:transport:<serial>
host:transport-any
host:transport-usb
host:transport-local
adb
client
Requests
a service execution
adb
client
adb
server
Requests
a service execution
Executes
host services
adb
daemon
adb
client
adb
server
Requests
a service execution
Executes
host services
Executes
local services
host:version Get the ADB Server version
host:kill Kill the ADB Server
host:devices List the connected devices
host:devices-l List the connected devices with details
host:track-devices Track the list of the connected devices
host:transport* Target a device to interact with
Some host services
shell:<command> Run a shell command
shell: Open an interactive shell session
remount: Remount the filesystem in r-w mode
framebuffer: Get framebuffer snapshots
jdwp:<pid> Connects to the JDWP thread of a process
track-jdwp Track the list of all processes in debug
sync: Specific service used for push & pull
Some local services
Server-Daemon
What the message looks like?
amessage
amessage
data
amessage
data
struct amessage {
unsigned command; /* command identifier constant */
unsigned arg0; /* first argument */
unsigned arg1; /* second argument */
unsigned data_length; /* length of payload (0 is allowed) */
unsigned data_crc32; /* crc32 of data payload */
unsigned magic; /* command ^ 0xffffffff */
};
amessage
data
struct amessage {
unsigned command; /* command identifier constant */
unsigned arg0; /* first argument */
unsigned arg1; /* second argument */
unsigned data_length; /* length of payload (0 is allowed) */
unsigned data_crc32; /* crc32 of data payload */
unsigned magic; /* command ^ 0xffffffff */
};
The verb of the action
amessage
data
struct amessage {
unsigned command; /* command identifier constant */
unsigned arg0; /* first argument */
unsigned arg1; /* second argument */
unsigned data_length; /* length of payload (0 is allowed) */
unsigned data_crc32; /* crc32 of data payload */
unsigned magic; /* command ^ 0xffffffff */
};
The arguments of the action
amessage
data
struct amessage {
unsigned command; /* command identifier constant */
unsigned arg0; /* first argument */
unsigned arg1; /* second argument */
unsigned data_length; /* length of payload (0 is allowed) */
unsigned data_crc32; /* crc32 of data payload */
unsigned magic; /* command ^ 0xffffffff */
};
The size of the data
adb connect <ip:port>
>
adb
daemon
adb
server
adb connect <ip:port>
>
adb
daemon
adb
server
adb connect <ip:port>
>
CNXN, 0x01000000, 256K
adb
daemon
adb
server
adb connect <ip:port>
>
CNXN, 0x01000000, 256K
Command
Arg 1
Arg 2
adb
daemon
adb
server
adb connect <ip:port>
>
CNXN, 0x01000000, 256K
CONNECT command
adb
daemon
adb
server
adb connect <ip:port>
>
CNXN, 0x01000000, 256K
Protocol version
adb
daemon
adb
server
adb connect <ip:port>
>
CNXN, 0x01000000, 256K
Max payload size
adb
daemon
adb
server
adb connect <ip:port>
>
CNXN, 0x01000000, 256K
device::ro.product...
adb
daemon
adb
server
adb connect <ip:port>
>
CNXN, 0x01000000, 256K
device::ro.product...
Command
Arg 1
Arg 2
adb
daemon
adb
server
adb connect <ip:port>
>
CNXN, 0x01000000, 256K
device::ro.product...
Data
adb
daemon
adb
server
adb connect <ip:port>
>
CNXN, 0x01000000, 256K
device::ro.product...
Device identity string
adb shell ls
>
adb
daemon
adb
server
adb shell ls
>
adb
daemon
adb
server
adb shell ls
>
OPEN, server-id, 0, shell:ls
adb
daemon
adb
server
adb shell ls
>
OPEN, server-id, 0, shell:ls
Command
Arg1
Arg2
Data
adb
daemon
adb
server
adb shell ls
>
OPEN, server-id, 0, shell:ls
The ADB service to execute
adb
daemon
adb
server
adb shell ls
>
OPEN, server-id, 0, shell:ls
OKAY, daemon-id, server-id
adb
daemon
adb
server
adb shell ls
>
OPEN, server-id, 0, shell:ls
OKAY, daemon-id, server-id
WRITE, daemon-id, server-id
“DATA”
adb
daemon
adb
server
adb shell ls
>
OPEN, server-id, 0, shell:ls
OKAY, daemon-id, server-id
WRITE, daemon-id, server-id
“DATA”
OKAY, server-id, daemon-id
adb
daemon
adb
server
adb shell ls
>
OPEN, server-id, 0, shell:ls
OKAY, daemon-id, server-id
WRITE, daemon-id, server-id
“DATA”
OKAY, server-id, daemon-id
WRITE, daemon-id, server-id
“DATA”
CLOSE, daemon-id, server-id
adb
daemon
adb
server
adb shell ls
>
OPEN, server-id, 0, shell:ls
OKAY, daemon-id, server-id
WRITE, daemon-id, server-id
“DATA”
OKAY, server-id, daemon-id
WRITE, daemon-id, server-id
“DATA”
OKAY, server-id, daemon-id
CLOSE, server-id, daemon-id
CLOSE, daemon-id, server-id
Why ADB is
now faster?
data (256KB)
amessage
Now
data (256KB)
amessage
amessage
data (4KB)
Now
Before
adb
daemon
adb
server
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
adb
daemon
adb
server
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
WRITE, “256KB DATA”
OKAY
OKAY
WRITE, “256KB DATA”
Develop on the ADB project
Configure your environment
Fetch the source code
Make it!
Build your own ADB
repo init \
-u https://android.googlesource.com/platform/manifest \
-b master
repo sync -c --force-sync
source build/envsetup.sh
lunch
make -j24 adb
>
>
>
>
>
adbd
adb
libadb
The client host binary
Bundle in the Android SDK
The one you use everyday
Output path
./out/host/<your-platform>/bin/adb
adb
The device’s daemon binary
Bundle in the Android OS
The one you use everyday
Maybe without noticing
adbd
Adb static library
Contains the common files
libadb
Originally written in
C
Aimed to be written in
C++
Actually written in
C+
Actually written in
C~++
Actually written in
C++--
ADB sources are ubiquitous
ADB sources are ubiquitous
ADB sources are ubiquitous
adb
daemon
adb
client
adb
server
ADB sources are ubiquitous
adb
daemon
adb
client
adb
server
adb
client
adb
server
adb
daemon
Nexus 6P
adb
daemon
Network device
adb
daemon
AS Emulator
adb
client
adb
client
#if ADB_HOST
...
#else // !ADB_HOST
...
#endif // ADB_HOST
#if ADB_HOST
...
#else // !ADB_HOST
...
#endif // ADB_HOST
62 times
#if defined(_WIN32)
...
#endif
#if defined(_WIN32)
...
#endif
51 times
adb kill-server
>
export ADB_TRACE=adb
>
Debug ADB
adb start-server
>
adb devices
>
...
adb I 39295 1708488 adb_client.cpp:135] _adb_connect:host:devices
adb I 39295 1708488 adb_io.cpp:99] writex: fd=3 len=16 30303063686f73743a64657669636573 000chost:devices
...
ADB Client logs
tail -f /tmp/adb.log Linux
tail -f $TMPDIR/adb.*.log Mac
ADB Server logs
>
>
ADB &
The Android Dev Tools
Android Studio
repo init \
-u https://android.googlesource.com/platform/manifest \
-b studio-master-dev
repo sync -c --force-sync
cd ./tools/idea
>
>
>
Get the source code
Android Studio
does not use
adb
Android Studio
does not use
adb
…almost
Android Studio
uses
ddmlib
A Java library
Behaves as an ADB Client
Part of the AOSP
tools/base/ddmlib
ddmlib
ddmlib
does not use
adb
ddmlib
does not use
adb
…almost
ddmlib
adb
server
adb
daemon
Nexus 6P
adb
daemon
Network device
adb
daemon
AS Emulator
5037
What’s the difference between ddmlib and adb binary?
What’s the difference between ddmlib and adb binary?
one of
s
What’s the difference between ddmlib and adb binary?
one of
s
The backward compatibility
adb binary
ddmlib
Latest version only
From ADB 1.0.20
adb binary
ddmlib
Latest version only
From ADB 1.0.20
(October 2008)
Maintained by Google
Open source
Many thousands of daily users
Still need the adb binary
ddmlib as library
Maintained by Google
Open source
Many thousands of daily users
Still need the adb binary
Possibly a good tool for your project
ddmlib as library
repositories {
google()
}
dependencies {
implementation 'com.android.tools.ddms:ddmlib:26.1.0'
}
The Android Gradle Plugin
repo init \
-u https://android.googlesource.com/platform/manifest \
-b gradle_3.0.0
repo sync -c --force-sync
cd ./tools/base/build-system/
>
>
>
Get the source code
The Android Gradle Plugin
uses
ddmlib
The Android Gradle Plugin
uses
ddmlib
Like Android Studio
The Android Gradle Plugin
uses
ddmlib
How does
?
When there is an interaction with a device
Install an APK
Launch instrumented tests
Get devices information
Manages the list of connected devices
Interacts with the device through ddmlib
DeviceProvider
ConnectedDevice
gradlew <yourTask> --debug
>
Make ddmlib verbose from the build.gradle
import com.android.ddmlib.DdmPreferences
DdmPreferences.setLogLevel("verbose")
Make ddmlib verbose from the build.gradle
V/ddms: execute: running pm install-create -r -S 945819
V/ddms: execute: running pm install-write -S 945819 26732 0_binocle-flavor1-debug -
V/ddms: execute: running pm install-commit 1802739235
…
V/ddms: execute: running am instrument -w -r com.genymotion.binocle.test/android.test.InstrumentationTestRunner
V/InstrumentationResultParser: INSTRUMENTATION_STATUS: numtests=5
V/InstrumentationResultParser: INSTRUMENTATION_STATUS: stream=
V/InstrumentationResultParser: com.genymotion.binocle.test.TestBattery:
V/InstrumentationResultParser: INSTRUMENTATION_STATUS: id=InstrumentationTestRunner
V/InstrumentationResultParser: INSTRUMENTATION_STATUS: test=testBatteryWarning
…
Inject ADB options from the build.gradle
for all the tasks
android.adbOptions {
timeOutInMs 5000 // 5 seconds
installOptions “-g”
}
Inject ADB options from the build.gradle
for a single task
android.testVariants.all { variant ->
variant.connectedInstrumentTest.installOptions = ["-g"]
}
http://eyal.fr
bit.ly/adb-chill
Thank you!
Slides
>
>