diff options
Diffstat (limited to 'src')
6 files changed, 234 insertions, 206 deletions
diff --git a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java index d65568fa..ac4c9b29 100755 --- a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java +++ b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java @@ -297,20 +297,6 @@ public class NavigationActivity extends Activity } } else if (intent.getAction().compareTo( - FileManagerSettings.INTENT_FILE_CHANGED) == 0) { - // Retrieve the file that was changed - String file = - intent.getStringExtra(FileManagerSettings.EXTRA_FILE_CHANGED_KEY); - try { - FileSystemObject fso = CommandHelper.getFileInfo(context, file, null); - if (fso != null) { - getCurrentNavigationView().refresh(fso); - } - } catch (Exception e) { - ExceptionUtil.translateException(context, e, true, false); - } - - } else if (intent.getAction().compareTo( FileManagerSettings.INTENT_THEME_CHANGED) == 0) { applyTheme(); @@ -644,7 +630,6 @@ public class NavigationActivity extends Activity if (curDir != null) { VirtualMountPointConsole vc = VirtualMountPointConsole.getVirtualConsoleForPath( mNavigationViews[mCurrentNavigationView].getCurrentDir()); - getCurrentNavigationView().refresh(true); if (vc != null && !vc.isMounted()) { onRequestBookmarksRefresh(); removeUnmountedHistory(); @@ -1942,10 +1927,6 @@ public class NavigationActivity extends Activity if (searchInfo != null && searchInfo.isSuccessNavigation()) { //Navigate to previous history back(); - } else { - // I don't know is the search view was changed, so try to do a refresh - // of the navigation view - getCurrentNavigationView().refresh(true); } } // reset bookmarks list to default as the user could have set a @@ -1982,13 +1963,6 @@ public class NavigationActivity extends Activity */ @Override public void onRequestRefresh(Object o, boolean clearSelection) { - if (o instanceof FileSystemObject) { - // Refresh only the item - this.getCurrentNavigationView().refresh((FileSystemObject)o); - } else if (o == null) { - // Refresh all - getCurrentNavigationView().refresh(); - } if (clearSelection) { this.getCurrentNavigationView().onDeselectAll(); } @@ -2008,13 +1982,8 @@ public class NavigationActivity extends Activity @Override public void onRequestRemove(Object o, boolean clearSelection) { if (o instanceof FileSystemObject) { - // Remove from view - this.getCurrentNavigationView().removeItem((FileSystemObject)o); - //Remove from history removeFromHistory((FileSystemObject)o); - } else { - onRequestRefresh(null, clearSelection); } if (clearSelection) { this.getCurrentNavigationView().onDeselectAll(); @@ -2367,19 +2336,8 @@ public class NavigationActivity extends Activity } } catch (Exception e) { - // Notify the user + // Do nothing, objects should be removed by the FileObserver in NavigationView ExceptionUtil.translateException(this, e); - - // Remove the object - if (e instanceof FileNotFoundException || e instanceof NoSuchFileOrDirectory) { - // If have a FileSystemObject reference then there is no need to search - // the path (less resources used) - if (item instanceof FileSystemObject) { - getCurrentNavigationView().removeItem((FileSystemObject)item); - } else { - getCurrentNavigationView().removeItem((String)item); - } - } return; } diff --git a/src/com/cyanogenmod/filemanager/model/Directory.java b/src/com/cyanogenmod/filemanager/model/Directory.java index 77b12081..47e53e20 100644 --- a/src/com/cyanogenmod/filemanager/model/Directory.java +++ b/src/com/cyanogenmod/filemanager/model/Directory.java @@ -37,6 +37,12 @@ public class Directory extends FileSystemObject { public static final char UNIX_ID = 'd'; /** + * Normally, you shouldn't call this, however, this is in to be able + * to further abstract some calls in FileHelper. + **/ + public Directory() {} + + /** * Constructor of <code>Directory</code>. * * @param name The name of the object diff --git a/src/com/cyanogenmod/filemanager/model/FileSystemObject.java b/src/com/cyanogenmod/filemanager/model/FileSystemObject.java index 578ea323..f82ff0b1 100644 --- a/src/com/cyanogenmod/filemanager/model/FileSystemObject.java +++ b/src/com/cyanogenmod/filemanager/model/FileSystemObject.java @@ -54,6 +54,12 @@ public abstract class FileSystemObject implements Serializable, Comparable<FileS private boolean mIsRemote; /** + * Normally, you shouldn't call this, however, this is in to be able + * to further abstract some calls in FileHelper. + **/ + public FileSystemObject() {} + + /** * Constructor of <code>FileSystemObject</code>. * * @param name The name of the object diff --git a/src/com/cyanogenmod/filemanager/model/RegularFile.java b/src/com/cyanogenmod/filemanager/model/RegularFile.java index 49c9fd77..cd8b8867 100644 --- a/src/com/cyanogenmod/filemanager/model/RegularFile.java +++ b/src/com/cyanogenmod/filemanager/model/RegularFile.java @@ -32,6 +32,12 @@ public class RegularFile extends FileSystemObject { public static final char UNIX_ID = '-'; /** + * Normally, you shouldn't call this, however, this is in to be able + * to further abstract some calls in FileHelper. + **/ + public RegularFile() {} + + /** * Constructor of <code>RegularFile</code>. * * @param name The name of the object diff --git a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java index 3510f2c1..d947bb89 100755 --- a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java +++ b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.res.TypedArray; import android.os.AsyncTask; +import android.os.FileObserver; import android.os.storage.StorageVolume; import android.util.AttributeSet; import android.util.Log; @@ -438,6 +439,8 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe // Restrictions private Map<DisplayRestrictions, Object> mRestrictions; + private FileObserver mCurrentDirObserver; + /** * @hide */ @@ -828,6 +831,7 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe public void recycle() { if (this.mAdapter != null) { this.mAdapter.dispose(); + this.mCurrentDirObserver.stopWatching(); } } @@ -941,38 +945,6 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe } /** - * Method that removes a {@link FileSystemObject} from the view - * - * @param fso The file system object - */ - public void removeItem(FileSystemObject fso) { - // Delete also from internal list - if (fso != null) { - int cc = this.mFiles.size()-1; - for (int i = cc; i >= 0; i--) { - FileSystemObject f = this.mFiles.get(i); - if (f != null && f.compareTo(fso) == 0) { - this.mFiles.remove(i); - break; - } - } - } - this.mAdapter.remove(fso); - } - - /** - * Method that removes a file system object from his path from the view - * - * @param path The file system object path - */ - public void removeItem(String path) { - FileSystemObject fso = this.mAdapter.getItem(path); - if (fso != null) { - this.mAdapter.remove(fso); - } - } - - /** * Method that returns the current directory. * * @return String The current directory @@ -1024,6 +996,10 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe final String newDir, final boolean addToHistory, final boolean reload, final boolean useCurrent, final SearchInfoParcelable searchInfo, final FileSystemObject scrollTo) { + if (mCurrentDirObserver != null) { + mCurrentDirObserver.stopWatching(); + mCurrentDirObserver = null; + } NavigationTask task = new NavigationTask(useCurrent, addToHistory, reload, searchInfo, scrollTo, mRestrictions, mChRooted); task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, newDir); @@ -1066,7 +1042,7 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe void onPostExecuteTask( List<FileSystemObject> files, boolean addToHistory, boolean isNewHistory, boolean hasChanged, SearchInfoParcelable searchInfo, - String newDir, final FileSystemObject scrollTo) { + final String newDir, final FileSystemObject scrollTo) { try { //Check that there is not errors and have some data if (files == null) { @@ -1105,6 +1081,66 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe //The current directory is now the "newDir" this.mCurrentDir = newDir; + mCurrentDirObserver = new FileObserver(newDir) { + @Override + public void onEvent(int event, final String path) { + Runnable runnable = null; + final String fullPath = newDir + '/' + path; + // This is done because the implementation doesn't match the documentation + // for FileObserver and we are given undocumented flags. + event &= FileObserver.ALL_EVENTS; + + switch (event) { + case FileObserver.CREATE: + case FileObserver.MOVED_TO: { + final FileSystemObject fso = FileHelper.createFileSystemObject( + new File(fullPath)); + + if (FileHelper.shouldShow(fso, mRestrictions, mChRooted)) { + runnable = new Runnable() { + @Override + public void run() { + mAdapter.add(fso); + // TODO: refactor to move this off of UI thread + mAdapter.sort(FileHelper.getSortComparator()); + } + }; + break; + } + } case FileObserver.DELETE: + case FileObserver.MOVED_FROM: { + runnable = new Runnable() { + @Override + public void run() { + mAdapter.remove(mAdapter.getItem(fullPath)); + } + }; + break; + } case FileObserver.DELETE_SELF: { + // TODO: Actually handle this + break; + + } case FileObserver.MODIFY: { + runnable = new Runnable() { + @Override + public void run() { + FileHelper.updateFileSystemObject(mAdapter.getItem(fullPath)); + mAdapter.notifyDataSetChanged(); + } + }; + break; + } + default: + Log.w(TAG, "Unknown event " + event + " for " + fullPath); + } + + if (runnable != null) { + post(runnable); + } + } + }; + mCurrentDirObserver.startWatching(); + if (this.mOnDirectoryChangedListener != null) { FileSystemObject dir = FileHelper.createFileSystemObject(new File(newDir)); this.mOnDirectoryChangedListener.onDirectoryChanged(dir); @@ -1240,11 +1276,6 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe */ @Override public void onRequestRefresh(Object o, boolean clearSelection) { - if (o instanceof FileSystemObject) { - refresh((FileSystemObject)o); - } else if (o == null) { - refresh(); - } if (clearSelection) { onDeselectAll(); } @@ -1263,11 +1294,6 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe */ @Override public void onRequestRemove(Object o, boolean clearSelection) { - if (o != null && o instanceof FileSystemObject) { - removeItem((FileSystemObject)o); - } else { - onRequestRefresh(null, clearSelection); - } if (clearSelection) { onDeselectAll(); } diff --git a/src/com/cyanogenmod/filemanager/util/FileHelper.java b/src/com/cyanogenmod/filemanager/util/FileHelper.java index 501092a6..b2389a96 100644 --- a/src/com/cyanogenmod/filemanager/util/FileHelper.java +++ b/src/com/cyanogenmod/filemanager/util/FileHelper.java @@ -515,6 +515,103 @@ public final class FileHelper { return fso; } + + public static boolean shouldShow(FileSystemObject file, + Map<DisplayRestrictions, Object> restrictions, + boolean chRooted) { + //Retrieve user preferences + SharedPreferences prefs = Preferences.getSharedPreferences(); + FileManagerSettings showHiddenPref = FileManagerSettings.SETTINGS_SHOW_HIDDEN; + FileManagerSettings showSystemPref = FileManagerSettings.SETTINGS_SHOW_SYSTEM; + FileManagerSettings showSymlinksPref = FileManagerSettings.SETTINGS_SHOW_SYMLINKS; + + //Hidden files + if (!prefs.getBoolean( + showHiddenPref.getId(), + ((Boolean)showHiddenPref.getDefaultValue()).booleanValue()) || chRooted) { + if (file.isHidden()) { + return false; + } + } + + //System files + if (!prefs.getBoolean( + showSystemPref.getId(), + ((Boolean)showSystemPref.getDefaultValue()).booleanValue()) || chRooted) { + if (file instanceof SystemFile) { + return false; + } + } + + //Symlinks files + if (!prefs.getBoolean( + showSymlinksPref.getId(), + ((Boolean)showSymlinksPref.getDefaultValue()).booleanValue()) || chRooted) { + if (file instanceof Symlink) { + return false; + } + } + + // Restrictions (only apply to files) + if (restrictions != null) { + if (!isDirectory(file)) { + if (!isDisplayAllowed(file, restrictions)) { + return false; + } + } + } + + return true; + } + + public static Comparator<FileSystemObject> getSortComparator() { + + //Retrieve user preferences + SharedPreferences prefs = Preferences.getSharedPreferences(); + FileManagerSettings sortModePref = FileManagerSettings.SETTINGS_SORT_MODE; + FileManagerSettings showDirsFirstPref = FileManagerSettings.SETTINGS_SHOW_DIRS_FIRST; + + final boolean showDirsFirst = + prefs.getBoolean( + showDirsFirstPref.getId(), + ((Boolean)showDirsFirstPref.getDefaultValue()).booleanValue()); + final NavigationSortMode sortMode = + NavigationSortMode.fromId( + prefs.getInt(sortModePref.getId(), + ((ObjectIdentifier) sortModePref.getDefaultValue()).getId())); + + return new Comparator<FileSystemObject>() { + @Override + public int compare(FileSystemObject lhs, FileSystemObject rhs) { + //Parent directory always goes first + boolean isLhsParentDirectory = lhs instanceof ParentDirectory; + boolean isRhsParentDirectory = rhs instanceof ParentDirectory; + if (isLhsParentDirectory || isRhsParentDirectory) { + if (isLhsParentDirectory && isRhsParentDirectory) { + return 0; + } + return (isLhsParentDirectory) ? -1 : 1; + } + + //Need to sort directory first? + if (showDirsFirst) { + boolean isLhsDirectory = FileHelper.isDirectory(lhs); + boolean isRhsDirectory = FileHelper.isDirectory(rhs); + if (isLhsDirectory || isRhsDirectory) { + if (isLhsDirectory && isRhsDirectory) { + //Apply sort mode + return FileHelper.doCompare(lhs, rhs, sortMode); + } + return (isLhsDirectory) ? -1 : 1; + } + } + + //Apply sort mode + return FileHelper.doCompare(lhs, rhs, sortMode); + } + }; + } + /** * Method that applies the configuration modes to the listed files * (sort mode, hidden files, ...). @@ -543,101 +640,18 @@ public final class FileHelper { public static List<FileSystemObject> applyUserPreferences( List<FileSystemObject> files, Map<DisplayRestrictions, Object> restrictions, boolean noSort, boolean chRooted) { - //Retrieve user preferences - SharedPreferences prefs = Preferences.getSharedPreferences(); - FileManagerSettings sortModePref = FileManagerSettings.SETTINGS_SORT_MODE; - FileManagerSettings showDirsFirstPref = FileManagerSettings.SETTINGS_SHOW_DIRS_FIRST; - FileManagerSettings showHiddenPref = FileManagerSettings.SETTINGS_SHOW_HIDDEN; - FileManagerSettings showSystemPref = FileManagerSettings.SETTINGS_SHOW_SYSTEM; - FileManagerSettings showSymlinksPref = FileManagerSettings.SETTINGS_SHOW_SYMLINKS; //Remove all unnecessary files (no required by the user) int cc = files.size(); for (int i = cc - 1; i >= 0; i--) { - FileSystemObject file = files.get(i); - - //Hidden files - if (!prefs.getBoolean( - showHiddenPref.getId(), - ((Boolean)showHiddenPref.getDefaultValue()).booleanValue()) || chRooted) { - if (file.isHidden()) { - files.remove(i); - continue; - } - } - - //System files - if (!prefs.getBoolean( - showSystemPref.getId(), - ((Boolean)showSystemPref.getDefaultValue()).booleanValue()) || chRooted) { - if (file instanceof SystemFile) { - files.remove(i); - continue; - } - } - - //Symlinks files - if (!prefs.getBoolean( - showSymlinksPref.getId(), - ((Boolean)showSymlinksPref.getDefaultValue()).booleanValue()) || chRooted) { - if (file instanceof Symlink) { - files.remove(i); - continue; - } - } - - // Restrictions (only apply to files) - if (restrictions != null) { - if (!isDirectory(file)) { - if (!isDisplayAllowed(file, restrictions)) { - files.remove(i); - continue; - } - } + if (!shouldShow(files.get(i), restrictions, chRooted)) { + files.remove(i); } } //Apply sort mode if (!noSort) { - final boolean showDirsFirst = - prefs.getBoolean( - showDirsFirstPref.getId(), - ((Boolean)showDirsFirstPref.getDefaultValue()).booleanValue()); - final NavigationSortMode sortMode = - NavigationSortMode.fromId( - prefs.getInt(sortModePref.getId(), - ((ObjectIdentifier)sortModePref.getDefaultValue()).getId())); - Collections.sort(files, new Comparator<FileSystemObject>() { - @Override - public int compare(FileSystemObject lhs, FileSystemObject rhs) { - //Parent directory always goes first - boolean isLhsParentDirectory = lhs instanceof ParentDirectory; - boolean isRhsParentDirectory = rhs instanceof ParentDirectory; - if (isLhsParentDirectory || isRhsParentDirectory) { - if (isLhsParentDirectory && isRhsParentDirectory) { - return 0; - } - return (isLhsParentDirectory) ? -1 : 1; - } - - //Need to sort directory first? - if (showDirsFirst) { - boolean isLhsDirectory = FileHelper.isDirectory(lhs); - boolean isRhsDirectory = FileHelper.isDirectory(rhs); - if (isLhsDirectory || isRhsDirectory) { - if (isLhsDirectory && isRhsDirectory) { - //Apply sort mode - return FileHelper.doCompare(lhs, rhs, sortMode); - } - return (isLhsDirectory) ? -1 : 1; - } - } - - //Apply sort mode - return FileHelper.doCompare(lhs, rhs, sortMode); - } - - }); + Collections.sort(files, getSortComparator()); } //Return the files @@ -1053,6 +1067,35 @@ public final class FileHelper { return relative.toString() + s1.substring(s2.length()); } + private static void applyFileToFileSystemObject(File file, FileSystemObject fso) { + // The user and group name of the files. Use the defaults one for sdcards + final String USER = "root"; //$NON-NLS-1$ + final String GROUP = "sdcard_r"; //$NON-NLS-1$ + + // The user and group name of the files. In ChRoot, aosp give restrict access to + // this user and group. This applies for permission also. This has no really much + // interest if we not allow to change the permissions + AID userAID = AIDHelper.getAIDFromName(USER); + AID groupAID = AIDHelper.getAIDFromName(GROUP); + User user = new User(userAID.getId(), userAID.getName()); + Group group = new Group(groupAID.getId(), groupAID.getName()); + Permissions perm = file.isDirectory() + ? Permissions.createDefaultFolderPermissions() + : Permissions.createDefaultFilePermissions(); + + // Build a directory? + Date lastModified = new Date(file.lastModified()); + + fso.setName(file.getName()); + fso.setParent(file.getParent()); + fso.setUser(user); + fso.setGroup(group); + fso.setPermissions(perm); + fso.setLastModifiedTime(lastModified); + fso.setLastAccessedTime(lastModified); + fso.setLastChangedTime(lastModified); + } + /** * Method that creates a {@link FileSystemObject} from a {@link File} * @@ -1061,46 +1104,29 @@ public final class FileHelper { */ public static FileSystemObject createFileSystemObject(File file) { try { - // The user and group name of the files. Use the defaults one for sdcards - final String USER = "root"; //$NON-NLS-1$ - final String GROUP = "sdcard_r"; //$NON-NLS-1$ - - // The user and group name of the files. In ChRoot, aosp give restrict access to - // this user and group. This applies for permission also. This has no really much - // interest if we not allow to change the permissions - AID userAID = AIDHelper.getAIDFromName(USER); - AID groupAID = AIDHelper.getAIDFromName(GROUP); - User user = new User(userAID.getId(), userAID.getName()); - Group group = new Group(groupAID.getId(), groupAID.getName()); - Permissions perm = file.isDirectory() - ? Permissions.createDefaultFolderPermissions() - : Permissions.createDefaultFilePermissions(); - - // Build a directory? - Date lastModified = new Date(file.lastModified()); - if (file.isDirectory()) { - return - new Directory( - file.getName(), - file.getParent(), - user, group, perm, - lastModified, lastModified, lastModified); // The only date we have - } - - // Build a regular file - return - new RegularFile( - file.getName(), - file.getParent(), - user, group, perm, - file.length(), - lastModified, lastModified, lastModified); // The only date we have + FileSystemObject fso = file.isDirectory() ? new Directory() : new RegularFile(); + applyFileToFileSystemObject(file, fso); + return fso; } catch (Exception e) { Log.e(TAG, "Exception retrieving the fso", e); //$NON-NLS-1$ } return null; } + + /** + * Method that updates a {@link FileSystemObject} + * + * @param fso The {@link FileSystemObject} to update + */ + public static void updateFileSystemObject(FileSystemObject fso) { + try { + applyFileToFileSystemObject(new File(fso.getFullPath()), fso); + } catch (Exception e) { + Log.e(TAG, "Failed to apply changes to " + fso.getFullPath(), e); + } + } + /** * Method that copies recursively to the destination * |