[Mostly written ]
This page contains some random facts about Android and hacking Android. They are written in an extremely terse form because they are mainly intended as a memento for myself, but maybe they can be useful for other people as well.
app_process utilitydumpsys utilitycom.android.inputmethod.latin)DUNAPN type
How to change the Linux kernel command line used in Android:
Install the abootimg program under Debian or
Ubuntu.
Using TWRP recovery (or
possibly some other one), back up the boot image. Copy the boot image
from this backup (TWRP calls
it boot.emmc.win — others might call it something
like boot.img). Feed it to abootimg -x
which will extract three files
(bootimg.cfg, initrd.img, zImage).
Edit the cmdline from the bootimg.cfg file
and run abootimg -u with the -f argument to
update the boot image file. It can then be flashed
using flashboot flash boot when the phone is in
bootloader.
Fastboot IMG files, at least those which are ext4
images, are not mountable (“raw”) partition images, but a special
(sparse
) format. To convert from and to that format, one needs
the simg2img and make_ext4fs programs (see
below). Use with something like ./simg2img input.img
output.raw.img to convert a sparse image to a mountable (“raw”)
image. Conversely, something like ./make_ext4fs -s -l $SIZE -a
userdata userdata-new.img mnt-point/ (as root, where $SIZE is
the size of the mountable image) to reconstruct a sparse image file
from a mounted directory; it may be necessary to specify
an SElinux file context file using the -S
option. See
also this
page on OMAPpedia.
These simg2img and make_ext4fs utilities
are distributed by various Linux distros (e.g., as part of the
Debian android-tools-fsutils package). Unfortunately,
the version in question might be too old, or not compiled with the
right options (some versions are simply not functional; others might
lack SElinux support).
Sadly, compiling simg2img and make_ext4fs
from the Android source is messy. Here are some hints:
simg2img, it's not too difficult, but
note that it seems to have disappeared from Android KitKat on. The
source resides
in the ext4_utils
directory of the platform/system/extras Git
repository. Compile with gcc -o simg2img simg2img.c
sparse_crc32.c -lm -lz (simple enough)!ext4_utils is a mess.
Here are some hints on compiling the Jelly Bean version: the source
can also be obtained
from the ext4_utils
directory in the platform/system/extras Git
repository of the Android sources, and it also
needs some
header files from the platform/system/core
repository. One is compiled with gcc -o simg2img simg2img.c
sparse_crc32.c -lm -lz and the other with gcc -I
/somewhere/core/include -o make_ext4fs make_ext4fs_main.c
make_ext4fs.c sparse_crc32.c contents.c allocate.c indirect.c extent.c
backed_block.c ext4_utils.c output_file.c uuid.c sha1.c wipe.c -lm -lz
-DANDROID (why does it always have to be so complicated?).
Sadly, this version does not have SElinux support (if you
compile with -DHAVE_SELINUX, it will simply
segfault).ext4_utils directory, but now we will also need
the Android
version of libselinux
and more core
files (those in the include but also
the libsparse directories). First
compile libselinux with something like this (run from
the src/ directory in its source): gcc -I
../include -I /somewhere/core/include -c *.c -DHOST; ar cru
libselinux.a *.o (the -DHOST is essential to avoid
an error about gettid() not found). Next
compile libsparse with: gcc -I include -I
/somewhere/core/include -c *.c; ar cru libsparse.a *.o (of
course, /somewhere/core/include should be the same
as ../include here). Finally, compile the program
with gcc -I /somewhere/core/include -I
/somewhere/core/libsparse/include -I /somewhere/libselinux/include -o
make_ext4fs make_ext4fs_main.c make_ext4fs.c contents.c allocate.c
indirect.c extent.c ext4_utils.c uuid.c sha1.c wipe.c crc16.c -lm -lz
/somewhere/libselinux/src/libselinux.a
/somewhere/core/libsparse/libsparse.a -DANDROID -DHAVE_SELINUX
(whew!). But that's not all: the -S option to
specify SElinux file contexts requires a file that can be
found in the boot.img file (see below).Finally, the boot.img file uses a different format!
This one is documented
in the bootimg.h
header file.
This
page is a good introduction to the Android property system.
The getprop and setprop utilities
(in /system/bin/, at least under CM) can be
used to manipulate them from the command line.
This
page contains a good starting introduction to the Android package
manager. The key file is /data/system/packages.xml; it
can, to some extent, be manipulated by the pm utility
(found in /system/bin/ — at least under CM;
but really just a wrapper
to CLASSPATH=/system/framework/pm.jar app_process
/system/bin com.android.commands.pm.Pm). For example, to find
the .apk file corresponding to a package, run something
like pm path com.example.somepackage (one can then use
this to read its manifest).
It seems one should be able to remove individual permissions from a
package by manipulating the /data/system/packages.xml
file; I haven't actually tried this.
Package restrictions are
in /data/system/users/0/package-restrictions.xml
(here, 0
is the default user ID because these are,
in fact, per-user restrictions): enabled or disabled individual
components are listed there (to find the components of a
package, look inside its manifest file),
but of course it is probably better to enable/disable components using
something like pm disable
com.example.somepackage/com.example.somepackage.SomeComponent
(omit the part after the / for disabling a whole
package).
The .apk files contain XML in a special
binary format. The aapt utility found in the Android
development tools can be used to dump it in a human-readable form,
e.g.: aapt d xmltree Whatever.apk AndroidManifest.xml
(see
also here).
See here
for the official documentation of the AndroidManifest.xml
file format.
app_process utilityThe app_process utility seems to be used to run Java
code at a fairly low
level: this page speaks a
bit about it. It's the program that starts the main zygote
:
see here for a
description of the Android zygote startup.
dumpsys utilityThe dumpsys program is a fantastically useful utility
which can dump a huge amount of information concerning an Android
system. With no parameter, it will dump information on all
“services” it knows about, which is a huge amount, starting with a
list of all the services in question (i.e.: look at the beginning of
the output for a list of all useful parameters which can be passed
to dumpsys). Among other things, dumpsys
power gives information about power management, dumpsys
cpuinfo about the CPU usage, dumpsys
battery about battery state, dumpsys activity
about the current activities, dumpsys package about all
installed packages, dumpsys meminfo
com.example.somepackage shows memory usage by a running app,
while dumpsys batteryinfo displays package by package
battery usage. Some services take parameters:
try dumpsys someservice -h for usage.
To enquire about the current wake locks,
read /sys/power/wake_lock to find the active locks,
or /proc/wakelocks to find stats about past locks — note
that one can create and destroy a wake lock by simply writing an
arbitrary name into /sys/power/wake_lock
and /sys/power/wake_unlock respectively. Also note that
Android does not automatically release wake locks when a
process dies (i.e., they are not garbage-collected in any sense).
See here
and there
for more details about Android wake locks.
The above concerns kernel wake locks. Android also
has userland wake locks, which are all reflected as a single
kernel wake lock, PowerManagerService: to enquire about
the userland wake locks, type dumpsys
power and look for the Wake Locks
section of the output
(it should list the number of userland wake locks held, with the
process corresponding to each).
The .kl file in /system/usr/keylayout/
defines the scancode→keycode correspondence table and
the .kcm file in /system/usr/keychars/
defines the corresponding characters. More
information here.
com.android.inputmethod.latin)Warning: This is a mess and these
instructions are probably incomplete, brittle and subject to random
change; moreover, they depend on the Android SDK
and NDK being installed
in /opt/android-* like I have them. Use this
as a guideline, do not copy blindly!
Get the source using Git:
git clone git://github.com/CyanogenMod/android_packages_inputmethods_LatinIME cd android_packages_inputmethods_LatinIME git checkout cm-10.1.2
Then we need to copy the Android support library and also
the com.android.inputmethodcommon source:
cd java cp /opt/android-sdk-linux_86/extras/android/compatibility/v4/android-support-v4.jar libs/ cp -a /opt/android-sdk-linux_86/samples/android-17/SoftKeyboard/src/com/android/inputmethodcommon src/com/android/
Generate the standard build.xml file (still in
the java/ dir):
/opt/android-sdk-linux_86/tools/android update project --path . --target android-17
To avoid compressing the .dict files in the
resources:
Copy the section of /opt/android-sdk-linux_86/tools/ant/build.xml
that starts with <target name="-package-resources"
depends="-crunch"> and copy it in
a <project> element in a
file custom_rules.xml then uncomment <nocompress
extension="dict" />
To compile the JNI interface:
pushd ../native/jni /opt/android-ndk-r8e/ndk-build popd mkdir libs/armeabi cp -a ../native/libs/armeabi/libjni_latinime.so libs/armeabi/
Finally, we should be able to do:
ant release
DUNAPN type
The following is probably obsolete in Android 6 or
later; at any rate, the settings database now seems to be
in /data/system/users/0/settings_global.xml and
whereabouts instead of settings.db as indicated
below.
This blog post (in French) speaks about it in more detail. For the benefit of those who can't read French:
The tether_dun_required preference seems to be used to
lock the phone into using an APN of type dun
when tethering. Relevant code is
in frameworks/base/services/java/com/android/server/connectivity/Tethering.java;
the APN type is maybe transmitted to the network
operator, I'm not sure (relevant code possibly somewhere
around frameworks/opt/telephony/src/java/com/android/internal/telephony/DataConnection.java
and frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmDataConnection.java).
For some reason, some people report tether_dun_required
being in the secure preferences whereas I've found it in
the global preferences. At any rate, one can edit the
settings database using
sqlite3 /data/data/com.android.providers.settings/databases/settings.db
and insert the value in the global preferences
using:
INSERT INTO global ( name, value ) VALUES ( 'tether_dun_required', 0 ) ;
Probably obsolete.
The Google services framework tries to download and install OTA firmware updates on certain devices (e.g., Nexus 4). On CM, this will fail, retry indefinitely, and use up a lot of bandwidth for nothing. See here for details. The following commands should disable the phenomenon:
pm disable com.google.android.gsf/com.google.android.gsf.update.SystemUpdateActivity pm disable com.google.android.gsf/com.google.android.gsf.update.SystemUpdateService pm disable com.google.android.gsf/com.google.android.gsf.update.SystemUpdateService\$Receiver
(See above for more about
the pm command.) The (open
source) Autostarts
Android app can also be used to disable the three components in
question.
I'm not sure whether it's a permanent fix, however
(it should persist over reboot, but who knows whether the
Google services framework has a way of re-enabling itself; check
in /data/system/users/0/package-restrictions.xml after a
reboot to make sure the components are, indeed, disabled). Also, some
people have reported a wake lock in Google
services (i.e., it prevents the phone from sleeping) with a similar
solution, but perhaps only because only part of the above components
were disabled.
They are contained in /system/fonts/; the
files /system/etc/system_fonts.xml
and /system/etc/fallback_fonts.xml specify which fonts
are used (the former defines the main font families, the latter which
fonts are used as fallbacks for missing characters).
The default configuration for the Wifi driver on the Nexus 4
enables extremely aggressive power-saving features which help preserve
battery life but break networking badly,
and IPv6
even more:
see here
for specific Nexus 4 issues,
and here
for a related issue. A much better behavior can be obtained by
putting both McastBcastFilter
and gEnableBmps to 0
in /system/etc/wifi/WCNSS_qcom_cfg.ini (the former
prevents dropping of broadcast and multicast frames, something which
completely and utterly breaks networking and IPv6 in
particular; the second disables Broadcast Mode Power
Management
: I don't understand the exact relation between the
two); perhaps also set gEnableSuspend to 2 to mitigate
some of the battery drain (I'm not at all sure). This, of course,
will have important consequences on battery life when Wifi is on:
there does not seem to be a way to have both satisfactory Wifi
behavior and satisfactory battery life, unfortunately — one has to
choose which is the lesser evil.