looio/roottools

installBinary() - feature requests

Opened this issue · 4 comments

Currently RootTools.installBinary() extracts a raw resource into 
/data/data/app.package/files/<foo>, optionally setting the permissions for a 
new file.  This is a useful library function, and I was wondering if it could 
be extended to cover some other common patterns:


1) If the destination file already exists, compare the checksum or content to 
the resource data, and if it matches, just skip it (assuming the permissions 
are correct).  This avoids unnecessary writes to the flash and risk of 
corrupting a good binary.

Here are a few examples of projects which could benefit from having a common 
library function perform the comparison:

https://github.com/pragma-/networklog/blob/master/src/com/googlecode/networklog/
SysUtils.java#L34

https://github.com/ukanth/afwall/blob/beta/src/dev/ukanth/ufirewall/Api.java#L13
06

https://github.com/project-voodoo/gstreamer-android-app/blob/0a11086950962e8f191
0e4e8acf882cb34b2f165/src/org/projectvoodoo/gstandroid/utils/Utils.java#L26

https://github.com/blacksmithlabs/NetworkRecorder/blob/4f5fb20cd33eb7f1ce58e2a52
e0b43c4fafd27c8/Network%20Recorder/src/main/java/com/blacksmithlabs/networkrecor
der/helpers/SysUtils.java#L42


2) If the destination file already exists and is out of date, delete it first.  
Trying to overwrite a binary that is currently executing will result in a "text 
file busy" error from the OS.  Deleting it then opening a new file creates a 
new inode, avoiding the problem.

One situation in which this may be preferable to just calling killProcess() is 
if a system process or another app could be running a binary with the same 
name.  e.g. if an app wants to update /system/bin/sh it probably will not want 
to kill all currently executing "sh" instances.


3) In many cases, an app will want to copy a raw binary resource into a file 
under /system instead of /data/data/app.package/files/.  This could include 
startup scripts under /system/etc/init.d, system utilities like busybox under 
/system/xbin, {cifs,tun}.ko under /system/lib/modules, etc.

Would it be possible to extend installBinary() so that if an absolute path is 
provided, it writes the resource data to a root-owned binary under /system 
similar to copyFile(), all in one easy step?  (Ideally this would include the 
logic from #1 and #2 above.)

Examples of apps having to "roll their own" implementation of this 
functionality:

https://github.com/carlson5/CQuest/blob/184af2fc39610808facacb74a67ebc1d3e2f4abf
/CS598rhk/src/edu/illinois/CS598rhk/MainActivity.java

https://github.com/j0b0sapi3n/cs188-caradhoc/blob/99250c38cd63cbf2c214c7b0518022
a8ebfcb951/src/edu/ncsu/AdhocClient/AdhocClient.java#L147


I can help write the code if desired.

Thanks.

Original issue reported on code.google.com by cerne...@gmail.com on 8 Sep 2013 at 6:56

A couple of other ideas occurred to me after I wrote the original request:


4) Checking several binaries during application startup from the UI thread may 
cause "red flashes" due to blocking disk I/O.  Should RootTools provide a 
non-blocking option which starts a background thread, and optionally issues a 
callback on the UI thread when finished?

(Is it safe to access raw resources from another thread?)

Or maybe RootTools should just trust the caller to run this operation from an 
AsyncTask.


5) In many cases, apps will want to extract several resources at the same time. 
 Is it worth taking a list of (resid, filename, mode) tuples and handling them 
all at once, returning a code indicating:

 - Success, no updates
 - Success, some/all updates
 - Failure on one or more resources


6) Many apps bundle separate sets of binaries for <=ARMv6, ARMv7, x86, and 
MIPS.  So if #5 is implemented, maybe the tuple looks more like:

(arm_resid, armv7_resid, x86_resid, mips_resid, filename, mode)

with RootTools checking the relevant system properties to figure out which one 
to copy over.

Original comment by cerne...@gmail.com on 10 Sep 2013 at 5:32

I have been meaning to introduce something like this for quite a while.
You actually push it beyond what I had thought about. I know that we will 
implement #1 and #2 at the very minimum.

-Chris.

Original comment by militate on 16 Sep 2013 at 8:29

  • Changed state: Accepted
  • Added labels: Type-Enhancement
  • Removed labels: Type-Defect
One more request:

7) Installer.installBinary() currently invokes Shell.startRootShell() to change 
perms on the extracted binary.  If we're just extracting to 
/data/data/app.package/files/, it should not be necessary to "su".  Changing 
this behavior would make installBinary() usable by non-root apps.

Original comment by cerne...@gmail.com on 23 Sep 2013 at 5:09

A small step in the right direction: installBinary() now updates a binary if it 
finds its MD5 checksum has changed.

Original comment by militate on 27 Sep 2013 at 2:34