Skip to content

Commit

Permalink
* fix(android): previewImage() fails to display in-memory blobs (#12279)
Browse files Browse the repository at this point in the history
- Regression introduced by Titanium 9.1.0

Fixes TIMOB-28246
  • Loading branch information
build authored Nov 20, 2020
1 parent 66e8d37 commit df9ba20
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -561,64 +561,18 @@ private void deleteTiTempFiles()
} finally {
// If failed to move existing folder to "trash", then do a blocking delete. (Should never happen.)
if (!wasTrashed) {
tryDeleteTree(nextDir);
TiFileHelper.getInstance().tryDeleteTree(nextDir);
}
}
}

// Async delete the "trash" directory tree.
Thread thread = new Thread(() -> {
tryDeleteTree(trashDir);
TiFileHelper.getInstance().tryDeleteTree(trashDir);
});
thread.start();
}

/**
* Recursively deletes the given directory tree.
* Will never throw an exception and will return the result as a boolean instead.
* @param file Reference to a file or directory. Can be null.
* @return
* Returns true if successfully deleted all files and folders under given directory tree.
* Returns false if at least 1 deletion failed or if given a null argument.
*/
private boolean tryDeleteTree(File file)
{
boolean wasSuccessful = false;
try {
wasSuccessful = deleteTree(file);
} catch (Throwable ex) {
Log.e(TAG, "Failed to delete directory tree: " + file, ex);
}
return wasSuccessful;
}

/**
* Recursively deletes the given directory tree.
* @param file Reference to a directory or a single file. Can be null, in which case this method no-ops.
* @return
* Returns true if successfully deleted all files and folders under given directory tree.
* Returns false if at least 1 deletion failed or if given a null argument.
* @exception SecurityException Thrown if don't have permission to delete at least 1 file in the tree.
*/
private boolean deleteTree(File file) throws SecurityException
{
// Validate argument.
if (file == null) {
return false;
}

// If given a directory, then recursively delete the entire tree.
boolean wasDeleted = true;
if (file.isDirectory()) {
for (File nextFile : file.listFiles()) {
wasDeleted = deleteTree(nextFile) && wasDeleted;
}
}

// Delete the given directory/file.
return (wasDeleted && file.delete());
}

public void setRootActivity(TiRootActivity rootActivity)
{
this.rootActivity = new WeakReference<TiRootActivity>(rootActivity);
Expand Down Expand Up @@ -1038,7 +992,6 @@ public void dispose()
{
TiActivityWindows.dispose();
TiActivitySupportHelpers.dispose();
TiFileHelper.getInstance().destroyTempFiles();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,8 @@
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

Expand Down Expand Up @@ -60,8 +55,6 @@ public class TiFileHelper
private SoftReference<Context> softContext;
private TiNinePatchHelper nph;

private ArrayList<File> tempFiles = new ArrayList<File>();

private static HashSet<String> resourcePathCache;
private static HashSet<String> foundResourcePathCache;
private static HashSet<String> notFoundResourcePathCache;
Expand Down Expand Up @@ -414,7 +407,7 @@ public void deployFromAssets(File dest) throws IOException
walkAssets(am, "", paths);

// TODO clean old dir
wipeDirectoryTree(dest);
deleteTree(dest);

// copy from assets to dest dir
BufferedInputStream bis = null;
Expand Down Expand Up @@ -469,7 +462,7 @@ public void deployFromAssets(File dest) throws IOException

public void deployFromZip(File fname, File dest) throws IOException
{
wipeDirectoryTree(dest);
deleteTree(dest);

ZipInputStream zis = null;
ZipEntry ze = null;
Expand Down Expand Up @@ -535,91 +528,78 @@ public void deployFromZip(File fname, File dest) throws IOException
}
}

public void wipeDirectoryTree(File path)
/**
* Recursively deletes the given directory tree.
* Will never throw an exception and will return the result as a boolean instead.
* @param file Reference to a file or directory. Can be null.
* @return
* Returns true if successfully deleted all files and folders under given directory tree.
* Returns false if at least 1 deletion failed or if given a null argument.
*/
public boolean tryDeleteTree(File file)
{
TreeSet<String> dirs = new TreeSet<String>(new Comparator<String>() {
public int compare(String o1, String o2)
{
return o1.compareTo(o2) * -1;
}
});

wipeDirectoryTree(path, dirs);

Iterator<String> d = dirs.iterator();
while (d.hasNext()) {
String fn = d.next();
File f = new File(fn);
Log.d(TAG, "Deleting Dir: " + f.getAbsolutePath(), Log.DEBUG_MODE);
f.delete();
try {
return deleteTree(file);
} catch (Throwable ex) {
Log.e(TAG, "Failed to delete directory tree: " + file, ex);
}
return false;
}

public File getTempFile(String suffix, boolean destroyOnExit) throws IOException
/**
* Recursively deletes the given directory tree.
* @param file Reference to a directory or a single file. Can be null, in which case this method no-ops.
* @return
* Returns true if successfully deleted all files and folders under given directory tree.
* Returns false if at least 1 deletion failed or if given a null argument.
* @exception SecurityException Thrown if don't have permission to delete at least 1 file in the tree.
*/
public boolean deleteTree(File file) throws SecurityException
{
File result = null;
Context context = softContext.get();
// Validate argument.
if (file == null) {
return false;
}

if (context != null) {
result = getTempFile(context.getCacheDir(), suffix, destroyOnExit);
// If given a directory, then recursively delete the entire tree.
boolean wasDeleted = true;
if (file.isDirectory()) {
for (File nextFile : file.listFiles()) {
wasDeleted = deleteTree(nextFile) && wasDeleted;
}
}
return result;

// Delete the given directory/file.
return (wasDeleted && file.delete());
}

public File getTempFile(File dir, String suffix, boolean destroyOnExit) throws IOException
public File getTempFile(String suffix, boolean destroyOnExit) throws IOException
{
if (!dir.exists()) {
dir.mkdirs();
}
final File result = new File(dir.getPath() + "/tia" + Math.abs(new Random().nextLong()) + suffix);

if (destroyOnExit) {
tempFiles.add(result);
}
return result;
TiApplication tiApp = TiApplication.getInstance();
File parentDir = destroyOnExit ? tiApp.getTiTempDir() : tiApp.getCacheDir();
return File.createTempFile("tia", suffix, parentDir);
}

public File getTempFileFromInputStream(InputStream is, String suffix, boolean destroyOnExit)
{
try {
File tempFile = getTempFile(suffix, destroyOnExit);

if (tempFile.exists()) {
try (FileOutputStream os = new FileOutputStream(tempFile)) {
byte[] bytes = new byte[1024];
int length;
FileOutputStream os = new FileOutputStream(tempFile);

while ((length = is.read(bytes)) != -1) {
os.write(bytes, 0, length);
}
os.close();
}
return tempFile;

} catch (FileNotFoundException e) {
Log.w(TAG, "Could not find temp file: " + suffix);
} catch (IOException e) {
} catch (Exception e) {
Log.w(TAG, "Error occurred while creating output stream from temp file: " + suffix);
}
return null;
}

public void destroyOnExit(File file)
{
tempFiles.add(file);
}

// Destroys all temporary files that have been created.
// This is called when the application is exited/destroyed.
public void destroyTempFiles()
{
for (File tempFile : tempFiles) {
tempFile.delete();
}

tempFiles.clear();
}

/**
* Creates/retrieves a data directory in which the application can place its own custom data files.
* @param privateStorage determines the location of the data directory. If this is true, the location is internal(app-data://),
Expand All @@ -640,24 +620,6 @@ public File getDataDirectory(boolean privateStorage)
return f;
}

private void wipeDirectoryTree(File path, SortedSet<String> dirs)
{
File[] files = path.listFiles();
if (files != null) {
int len = files.length;
for (int i = 0; i < len; i++) {
File f = files[i];
if (f.isDirectory()) {
dirs.add(f.getAbsolutePath());
wipeDirectoryTree(f, dirs);
} else {
Log.d(TAG, "Deleting File: " + f.getAbsolutePath(), Log.DEBUG_MODE);
f.delete();
}
}
}
}

private void walkAssets(AssetManager am, String path, ArrayList<String> paths) throws IOException
{
if (titaniumPath(path)) {
Expand Down

0 comments on commit df9ba20

Please sign in to comment.