Is it possible to achieve locally (using adb
or other ways) what Google Play is doing in "Smart app updates" ?
What I want to do is to create a binary diff on the PC (using some command line tools) and then deploy the diff to simulator/device using Android tools (adb, shell, etc).
I am aware of
https://android.stackexchange.com/questions/36421/what-is-the-applypatch-tool-and-how-does-one-use-it
which doesn't provide any info about HOW to actually create and apply patches, just WHAT adb shell applypatch
is.
I tried to take a quick look at the C++ Android implementation code here which does the patching: https://android.googlesource.com/platform/bootable/recovery/+/master/applypatch/main.cpp#167
So far I created a binary diff using bsdiff, which apparently uses same algorithm with what Google Play and Android is using. But I don't know how to actually apply the patch.
EDIT: To clarify, here's a good example:
- I have
com.appv1.apk
on my PC and also installed on the device/emulator.
- I have
com.appv2.apk
on my PC.
- Using
bsdiff
I create the binary diff between com.appv1.apk
and com.appv2.apk
called let's say diff.bin
Now, what is the actual adb
command I need to run to deploy diff.bin
on the device/emulator such that after deploying the diff, com.appv1.apk
on the device/emulator becomes com.appv2.apk
?
I would say that between the usage print out:
usage: applypatch [-b <bonus-file>] <src-file> <tgt-file> <tgt-sha1> <tgt-size> [<src-sha1>:<patch> ...]
or applypatch -c <file> [<sha1> ...]
or applypatch -s <bytes>
or applypatch -l
Filenames may be of the form
MTD:<partition>:<len_1>:<sha1_1>:<len_2>:<sha1_2>:...
to specify reading from or writing to an MTD partition.
and the comments below:
// This program applies binary patches to files in a way that is safe
// (the original file is not touched until we have the desired
// replacement for it) and idempotent (it's okay to run this program
// multiple times).
//
// - if the sha1 hash of <tgt-file> is <tgt-sha1>, does nothing and exits
// successfully.
//
// - otherwise, if no <src-sha1>:<patch> is provided, flashes <tgt-file> with
// <src-file>. <tgt-file> must be a partition name, while <src-file> must
// be a regular image file. <src-file> will not be deleted on success.
//
// - otherwise, if the sha1 hash of <src-file> is <src-sha1>, applies the
// bsdiff <patch> to <src-file> to produce a new file (the type of patch
// is automatically detected from the file header). If that new
// file has sha1 hash <tgt-sha1>, moves it to replace <tgt-file>, and
// exits successfully. Note that if <src-file> and <tgt-file> are
// not the same, <src-file> is NOT deleted on success. <tgt-file>
// may be the string "-" to mean "the same as src-file".
//
// - otherwise, or if any error is encountered, exits with non-zero
// status.
//
// <src-file> (or <file> in check mode) may refer to an EMMC partition
// to read the source data. See the comments for the
// LoadPartitionContents() function for the format of such a filename.
it is pretty straight-forward.
So the basic command to patch com.appv1.apk
with diff.bin
and save the result to the com.appv2.apk
would be:
applypatch com.appv1.apk com.appv2.apk <com.appv2.apk SHA1> <com.appv2.apk size> <com.appv1.apk SHA1>:diff.bin