0

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.binon the device/emulator such that after deploying the diff, com.appv1.apk on the device/emulator becomes com.appv2.apk ?

Community
  • 1
  • 1
WriteEatSleepRepeat
  • 3,083
  • 3
  • 33
  • 56
  • you found the source code for `applypatch/main.cpp` already. besides the *usage* print out code it contains a more detailed description of all optional parameters in the comments. what is your exact problem? – Alex P. Sep 15 '16 at 14:16
  • @Alex.P I edited with example – WriteEatSleepRepeat Sep 15 '16 at 18:48
  • google servers send the delta to the GooglePlay.apk on the device and the GooglePlay.apk finish the build. It's all automatically done by google and we developers don't need to worry about it. GooglePlay.apk has special permissions, you will need a rooted phone I would assume, to do it yourself. Have you considered using external DEX files ? – Jon Goodwin Sep 15 '16 at 19:09
  • @JonGoodwin my intention is to do the patching myself using `adb` or some other way on the PC. it's not about worrying about it. what are "DEX files" ? – WriteEatSleepRepeat Sep 15 '16 at 19:23
  • Dalvik Executables (DEX), basically .jar files which you can run. see http://stackoverflow.com/questions/39175169/how-to-build-an-apk-and-separate-libraries-that-the-app-loads-dynamically/39278805#39278805 – Jon Goodwin Sep 15 '16 at 20:22
  • @JonGoodwin I don't understand what does DEX files have to do with the example I gave – WriteEatSleepRepeat Sep 15 '16 at 22:45
  • It's a way of updating your apk, without re-installing the whole thing, incremental updates, like "Smart app updates", it means if you have limited bandwidth for example, you don't have to send over so much data. This is "another way" to do that. Plus you don't have to be root, or figure out how to do it. – Jon Goodwin Sep 15 '16 at 22:51
  • @JonGoodwin I read your answer there but I don't understand it. Could you please give an answer here with steps I have to do(what exact command I have to run) for my example above with `com.appv1.apk` and `com.appv2.apk` – WriteEatSleepRepeat Sep 16 '16 at 07:22
  • check out https://github.com/Tencent/tinker – Alex P. Oct 17 '16 at 17:06
  • @Alex.P nice, thank you. ! – WriteEatSleepRepeat Oct 17 '16 at 17:26

1 Answers1

1

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
Alex P.
  • 30,437
  • 17
  • 118
  • 169
  • `applypatch` is a command run by `adb shell`. what's `old_file` and `new file` ? are these file paths? is `new_file` the local file path on my PC to the binary diff (created by bsdiff)? – WriteEatSleepRepeat Sep 15 '16 at 18:43
  • @Alex.P please see the example – WriteEatSleepRepeat Sep 15 '16 at 18:48
  • @Alex.P hi, looking forward for your thoughts, thanks – WriteEatSleepRepeat Sep 16 '16 at 07:20
  • @Alex.P I tried this: `adb.exe shell applypatch D:\Test\v1.apk D:\Test\v2.apk af92847783c124bc354a085f05cf60ab15a96153 18874337 19d12d6c2ba0a1c7bf1ae060c5dad38345e11b9b:D:\Test\diff.bin` but it gives me an error saying `failed to stat "D:Testdiff.bin": No such file or directory failed to parse patch args` – WriteEatSleepRepeat Sep 17 '16 at 11:29
  • I don't think it expects a path there for the diff file – WriteEatSleepRepeat Sep 17 '16 at 11:30
  • I explained in the comments to my answer to your previous question that all files need to be `push`ed to the device first. you need to remember those things - I don't like repeating myself. Or you could have just applied some minimal logic - an application running on the device only has access to the local file system - so all file paths should be local (to the device) – Alex P. Sep 17 '16 at 14:13
  • arghhh, sorry! I missed that dude! Patience with the noobs please :) and many thanks again for taking time to respond! you rock – WriteEatSleepRepeat Sep 17 '16 at 14:44
  • The proper way to say *you rock* is by accepting and upvoting the helpful answer – Alex P. Oct 17 '16 at 17:06
  • I kind of gave up on this. I haven't been able to check all the stuff. But here you go. – WriteEatSleepRepeat Oct 17 '16 at 17:27