Skip to content

Commit

Permalink
*): Add InstallAssetsBinary API.
Browse files Browse the repository at this point in the history
  • Loading branch information
tbfly committed Aug 5, 2014
1 parent 000d4e8 commit fd3fde4
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 5 deletions.
32 changes: 32 additions & 0 deletions RootTools/src/com/stericson/RootTools/RootTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,38 @@ public static boolean installBinary(Context context, int sourceId, String binary
return installBinary(context, sourceId, binaryName, "700");
}

/**
* This method can be used to unpack a binary from the assets folder and store it in
* /data/data/app.package/files/ This is typically useful if you provide your own C- or
* C++-based binary. This binary can then be executed using sendShell() and its full path.
*
* @param context the current activity's <code>Context</code>
* @param srcName asset source file Name
* @param destName destination file name; appended to /data/data/app.package/files/
* @param mode chmod value for this file
* @return a <code>boolean</code> which indicates whether or not we were able to create the new
* file.
*/
public static boolean installAssetsBinary(Context context, String srcName, String destName, String mode) {
return getInternals().installAssetsBinary(context, srcName, destName, mode);
}

/**
* This method can be used to unpack a binary from the assets folder and store it in
* /data/data/app.package/files/ This is typically useful if you provide your own C- or
* C++-based binary. This binary can then be executed using sendShell() and its full path.
*
* @param context the current activity's <code>Context</code>
* @param srcName the asset sourcd file name
* @param binaryName destination file name; appended to /data/data/app.package/files/
* @return a <code>boolean</code> which indicates whether or not we were able to create the new
* file.
*/
public static boolean installAssetsBinary(Context context, String srcName, String binaryName) {
return installAssetsBinary(context, srcName, binaryName, "700");
}


/**
* This method checks whether a binary is installed.
*
Expand Down
124 changes: 120 additions & 4 deletions RootTools/src/com/stericson/RootTools/internal/Installer.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import com.stericson.RootTools.execution.Shell;

import android.content.Context;
import android.content.res.AssetManager;

class Installer {

Expand Down Expand Up @@ -123,10 +124,125 @@ protected boolean installBinary(int sourceId, String destName, String mode) {
FileChannel ofc = oss.getChannel();
long pos = 0;
try {
long size = iss.available();
while ((pos += ofc.transferFrom(rfc, pos, size- pos)) < size)
;
} catch (IOException ex) {
long size = iss.available();
while ((pos += ofc.transferFrom(rfc, pos, size- pos)) < size)
;
} catch (IOException ex) {
if (RootTools.debugMode) {
Log.e(LOG_TAG, ex.toString());
}
return false;
}
} catch (FileNotFoundException ex) {
if (RootTools.debugMode) {
Log.e(LOG_TAG, ex.toString());
}
return false;
} finally {
if (oss != null) {
try {
oss.flush();
oss.getFD().sync();
oss.close();
} catch (Exception e) {
}
}
}
try {
iss.close();
} catch (IOException ex) {
if (RootTools.debugMode) {
Log.e(LOG_TAG, ex.toString());
}
return false;
}

try {
CommandCapture command = new CommandCapture(0, false, "chmod " + mode + " " + filesPath + File.separator + destName);
Shell.startRootShell().add(command);
commandWait(command);

} catch (Exception e) {}
}
return true;
}

/**
* This method can be used to unpack a binary from the assets folder and store it in
* /data/data/app.package/files/
* This is typically useful if you provide your own C- or C++-based binary.
* This binary can then be executed using sendShell() and its full path.
*
* @param srcName asset source file Name
* @param destName destination file name; appended to /data/data/app.package/files/
* @param mode chmod value for this file
* @return a <code>boolean</code> which indicates whether or not we were
* able to create the new file.
*/
protected boolean installAssetsBinary(String srcName, String destName, String mode) {
File mf = new File(filesPath + File.separator + destName);
InputStream in = null;
try {
AssetManager am = context.getAssets();
in = am.open(srcName);
if (in == null) {
return false;
}
} catch (Exception ex) {
if (RootTools.debugMode) {
Log.e(LOG_TAG, ex.toString());
}
}

if (!mf.exists() ||
!getFileSignature(mf).equals(
getStreamSignature(in)
)) {
Log.e(LOG_TAG, "Installing a new version of binary: " + destName);
// First, does our files/ directory even exist?
// We cannot wait for android to lazily create it as we will soon
// need it.
try {
FileInputStream fis = context.openFileInput(BOGUS_FILE_NAME);
fis.close();
} catch (FileNotFoundException e) {
FileOutputStream fos = null;
try {
fos = context.openFileOutput("bogus", Context.MODE_PRIVATE);
fos.write("justcreatedfilesdirectory".getBytes());
} catch (Exception ex) {
if (RootTools.debugMode) {
Log.e(LOG_TAG, ex.toString());
}
return false;
} finally {
if (null != fos) {
try {
fos.close();
context.deleteFile(BOGUS_FILE_NAME);
} catch (IOException e1) {}
}
}
} catch (IOException ex) {
if (RootTools.debugMode) {
Log.e(LOG_TAG, ex.toString());
}
return false;
}

// Only now can we start creating our actual file
InputStream iss = in;
ReadableByteChannel rfc = Channels.newChannel(iss);
FileOutputStream oss = null;
try {
oss = new FileOutputStream(mf);
FileChannel ofc = oss.getChannel();
long pos = 0;
try {
long size = iss.available();
while ((pos += ofc.transferFrom(rfc, pos, size- pos)) < size)
;
} catch (IOException ex) {
if (RootTools.debugMode) {
Log.e(LOG_TAG, ex.toString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,34 @@ public boolean installBinary(Context context, int sourceId, String destName, Str
return (installer.installBinary(sourceId, destName, mode));
}

/**
* This method can be used to unpack a binary from the assets folder and store it in
* /data/data/app.package/files/ This is typically useful if you provide your own C- or
* C++-based binary. This binary can then be executed using sendShell() and its full path.
*
* @param context the current activity's <code>Context</code>
* @param srcName asset source file name
* @param destName destination file name; appended to /data/data/app.package/files/
* @param mode chmod value for this file
* @return a <code>boolean</code> which indicates whether or not we were able to create the new
* file.
*/
public boolean installAssetsBinary(Context context, String srcName, String destName, String mode) {
Installer installer;

try {
installer = new Installer(context);
} catch (IOException ex) {
if (RootTools.debugMode) {
ex.printStackTrace();
}
return false;
}

return (installer.installAssetsBinary(srcName, destName, mode));
}


/**
* This method checks whether a binary is installed.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,19 @@ public void run() {
// First test: Install a binary file for future use
// if it wasn't already installed.
/*
Context mContext = getApplicationContext();
visualUpdate(TestHandler.ACTION_PDISPLAY, "Installing binary if needed");
if(false == RootTools.installBinary(mContext, R.raw.nes, "nes_binary")) {
visualUpdate(TestHandler.ACTION_HIDE, "ERROR: Failed to install binary. Please see log file.");
return;
}
*/
visualUpdate(TestHandler.ACTION_PDISPLAY, "Installing assets binary if needed");
if(false == RootTools.installAssetsBinary(mContext, "nes_binary", "nes_binary")) {
visualUpdate(TestHandler.ACTION_HIDE, "ERROR: Failed to install assert binary. Please see log file.");
return;
}
*/

boolean result;

Expand Down

0 comments on commit fd3fde4

Please sign in to comment.