aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2013-01-05 18:07:56 +0100
committerJorge Ruesga <jorge@ruesga.com>2013-01-05 18:16:46 +0100
commit0a127e51a4acc8005b9d7adf0432cb89627a8a5d (patch)
treec630c866632eadc8f33c48d48fc6c4a68edd74da
parentea585f4cdc5ea534c1b01519faacfee8e34db7c2 (diff)
downloadandroid_packages_apps_CMFileManager-0a127e51a4acc8005b9d7adf0432cb89627a8a5d.tar.gz
android_packages_apps_CMFileManager-0a127e51a4acc8005b9d7adf0432cb89627a8a5d.tar.bz2
android_packages_apps_CMFileManager-0a127e51a4acc8005b9d7adf0432cb89627a8a5d.zip
CMFM: Fixes and Improvements
* Some performance improvements: - Use stat instead of ls. This allow improve listing of directories with symlinks. Symlinks are resolved by File.getCanonicalFile. - Simplify ls, fileinfo, find and readlink command - Simplify the parsing of FolderUsage (only type, size and category is required), and avoid to load a lot of on unused objects - Add new file datetime information from stat: access, change and modify - Improve list, find and resolvelink java commands * FadeEffect and symlink handling * Remove context from AIDHelper and add new helpful methods * New getAbsolutePath method * Use file separator for paths and ROOT_DIRECTORY for root directory path * Organize startup - Initialize variables prior to register receivers - Load AID data for improve performance through caching - Load the theme base used by AOSP widgets * Allow Editor to show zero-length files Allow the editor to load zero-length files (like /proc/mounts) and change the buffer type to no editable in binary files. * Invert allowed mount points detection. This change inverts the algorithm for prevent unmount needed rw filesystems. Now uses known restricted filesystems instead of known allowed filesystems. Now filesystems like yaffs2, fuse, and other linux filesystems are allowed by default. * Remove unused xliff namespace * Add flagNoFullscreen to EditText widgets * Fix listview selectors of history and bookmarks * Fix race condition When the command was executed prior to block the execution, the thread wait for the timeout. Add a sync access check to ensure that prior to lock and wait the program executed is not finished. * Fix for async programs When the partial buffer received for an async program is not complete (ends with a EOL), the partial buffer was discarded. Add a new buffer with this lost chars to complete this bytes next time * Fix list command Use -n1 for xargs in list command to prevent "argument line too long" * If parent is null then assume that it is the root folder * Use only name and parent for equals method on FileSystemObject A FileSystemObject is the same if his name and path are the same. * Increase performance of adapters Use argument data when possible to avoid call the adapter methods * Do not clear selection on some actions Actions like create new file/folder, show properties and other actions that explicit requires clear the active selection, shouldn't removed the active selection. * Add a new additional line to dialog messages to fill the dialog * Fix spanish translations * Fix theme roulette on tablets * Clean NLS and Override warnings * Fix parse size data with dots * Add listeners after set the values to avoid raising triggers * Increase performance of adapters. Notify the data changed at the end of the changes, and only to super adapters (the internal structure has already been updated) * Ensure that all the Cursor references were closed after used them. * Remove unused SuppressLint * Clean up Change-Id: I4326e97cbc942c767829f1a0ff6b380ad768cfef Signed-off-by: jruesga <jorge@ruesga.com>
-rw-r--r--res/layout-sw600dp/theme_view.xml64
-rw-r--r--res/layout-sw720dp/theme_view.xml64
-rw-r--r--res/layout/bookmarks_item.xml2
-rw-r--r--res/layout/editor.xml1
-rw-r--r--res/layout/history_item.xml2
-rw-r--r--res/layout/inline_autocomplete.xml3
-rw-r--r--res/layout/input_name_dialog.xml2
-rw-r--r--res/layout/navigation.xml1
-rw-r--r--res/values-es/strings.xml8
-rw-r--r--res/values/dimen.xml3
-rw-r--r--res/values/overlay.xml1
-rw-r--r--res/xml/command_list.xml16
-rw-r--r--src/com/cyanogenmod/filemanager/FileManagerApplication.java101
-rw-r--r--src/com/cyanogenmod/filemanager/activities/BookmarksActivity.java23
-rw-r--r--src/com/cyanogenmod/filemanager/activities/EditorActivity.java6
-rw-r--r--src/com/cyanogenmod/filemanager/activities/NavigationActivity.java24
-rw-r--r--src/com/cyanogenmod/filemanager/activities/SearchActivity.java111
-rw-r--r--src/com/cyanogenmod/filemanager/adapters/AssociationsAdapter.java12
-rw-r--r--src/com/cyanogenmod/filemanager/adapters/BookmarksAdapter.java14
-rw-r--r--src/com/cyanogenmod/filemanager/adapters/CheckableListAdapter.java2
-rw-r--r--src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java18
-rw-r--r--src/com/cyanogenmod/filemanager/adapters/HistoryAdapter.java16
-rw-r--r--src/com/cyanogenmod/filemanager/adapters/SearchResultAdapter.java12
-rw-r--r--src/com/cyanogenmod/filemanager/commands/ExecutableCreator.java181
-rw-r--r--src/com/cyanogenmod/filemanager/commands/java/DiskUsageCommand.java34
-rw-r--r--src/com/cyanogenmod/filemanager/commands/java/FindCommand.java9
-rw-r--r--src/com/cyanogenmod/filemanager/commands/java/JavaExecutableCreator.java8
-rw-r--r--src/com/cyanogenmod/filemanager/commands/java/ListCommand.java10
-rw-r--r--src/com/cyanogenmod/filemanager/commands/java/ResolveLinkCommand.java8
-rw-r--r--src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgram.java8
-rw-r--r--src/com/cyanogenmod/filemanager/commands/shell/FindCommand.java92
-rw-r--r--src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java131
-rw-r--r--src/com/cyanogenmod/filemanager/commands/shell/ListCommand.java245
-rw-r--r--src/com/cyanogenmod/filemanager/commands/shell/ReadCommand.java8
-rw-r--r--src/com/cyanogenmod/filemanager/commands/shell/ResolveLinkCommand.java9
-rw-r--r--src/com/cyanogenmod/filemanager/commands/shell/ShellExecutableCreator.java3
-rw-r--r--src/com/cyanogenmod/filemanager/commands/shell/SyncResultProgram.java1
-rw-r--r--src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java103
-rw-r--r--src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java6
-rw-r--r--src/com/cyanogenmod/filemanager/model/BlockDevice.java12
-rw-r--r--src/com/cyanogenmod/filemanager/model/CharacterDevice.java11
-rw-r--r--src/com/cyanogenmod/filemanager/model/Directory.java9
-rw-r--r--src/com/cyanogenmod/filemanager/model/DomainSocket.java12
-rw-r--r--src/com/cyanogenmod/filemanager/model/FileSystemObject.java162
-rw-r--r--src/com/cyanogenmod/filemanager/model/NamedPipe.java12
-rw-r--r--src/com/cyanogenmod/filemanager/model/ParentDirectory.java4
-rw-r--r--src/com/cyanogenmod/filemanager/model/RegularFile.java14
-rw-r--r--src/com/cyanogenmod/filemanager/model/Symlink.java13
-rw-r--r--src/com/cyanogenmod/filemanager/model/SystemFile.java12
-rw-r--r--src/com/cyanogenmod/filemanager/preferences/Bookmarks.java32
-rw-r--r--src/com/cyanogenmod/filemanager/ui/dialogs/ActionsDialog.java2
-rw-r--r--src/com/cyanogenmod/filemanager/ui/dialogs/FilesystemInfoDialog.java4
-rw-r--r--src/com/cyanogenmod/filemanager/ui/dialogs/FsoPropertiesDialog.java27
-rw-r--r--src/com/cyanogenmod/filemanager/ui/policy/CompressActionPolicy.java4
-rw-r--r--src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java2
-rw-r--r--src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java4
-rw-r--r--src/com/cyanogenmod/filemanager/ui/policy/InfoActionPolicy.java2
-rw-r--r--src/com/cyanogenmod/filemanager/ui/policy/NewActionPolicy.java8
-rw-r--r--src/com/cyanogenmod/filemanager/ui/preferences/ThemeRoulette.java11
-rw-r--r--src/com/cyanogenmod/filemanager/ui/preferences/ThemeSelectorPreference.java10
-rw-r--r--src/com/cyanogenmod/filemanager/ui/widgets/DirectoryInlineAutocompleteTextView.java21
-rw-r--r--src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java98
-rw-r--r--src/com/cyanogenmod/filemanager/util/AIDHelper.java36
-rw-r--r--src/com/cyanogenmod/filemanager/util/CommandHelper.java35
-rw-r--r--src/com/cyanogenmod/filemanager/util/DialogHelper.java4
-rw-r--r--src/com/cyanogenmod/filemanager/util/FileHelper.java64
-rw-r--r--src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java38
-rw-r--r--src/com/cyanogenmod/filemanager/util/MountPointHelper.java22
-rw-r--r--src/com/cyanogenmod/filemanager/util/ParseHelper.java558
-rw-r--r--tests/src/com/cyanogenmod/filemanager/commands/shell/CompressCommandTest.java10
-rw-r--r--tests/src/com/cyanogenmod/filemanager/commands/shell/ExecCommandTest.java9
-rw-r--r--tests/src/com/cyanogenmod/filemanager/commands/shell/FindCommandTest.java30
-rw-r--r--tests/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommandTest.java5
-rw-r--r--tests/src/com/cyanogenmod/filemanager/commands/shell/ListCommandTest.java98
-rw-r--r--tests/src/com/cyanogenmod/filemanager/commands/shell/ReadCommandTest.java5
-rw-r--r--tests/src/com/cyanogenmod/filemanager/commands/shell/UncompressCommandTest.java5
-rw-r--r--tests/src/com/cyanogenmod/filemanager/commands/shell/WriteCommandTest.java16
-rw-r--r--themes/res/values/arrays.xml2
78 files changed, 1616 insertions, 1169 deletions
diff --git a/res/layout-sw600dp/theme_view.xml b/res/layout-sw600dp/theme_view.xml
new file mode 100644
index 00000000..356d1070
--- /dev/null
+++ b/res/layout-sw600dp/theme_view.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<com.cyanogenmod.filemanager.ui.preferences.ThemeView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="1dp"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/theme_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:gravity="center"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:textAppearance="@style/primary_text_appearance" />
+
+ <TextView
+ android:id="@+id/theme_author"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/theme_name"
+ android:gravity="center"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:textAppearance="@style/primary_text_appearance_nohighlight" />
+
+ <TextView
+ android:id="@+id/theme_desc"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:gravity="center"
+ android:ellipsize="end"
+ android:singleLine="false"
+ android:maxLines="2"
+ android:textAppearance="@style/secondary_text_appearance" />
+
+ <ImageView
+ android:id="@+id/theme_preview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_above="@id/theme_desc"
+ android:layout_below="@id/theme_author"
+ android:padding="@dimen/extra_large_margin"
+ android:layout_gravity="center"
+ android:scaleType="centerInside"
+ android:contentDescription="@null" />
+
+</com.cyanogenmod.filemanager.ui.preferences.ThemeView>
diff --git a/res/layout-sw720dp/theme_view.xml b/res/layout-sw720dp/theme_view.xml
new file mode 100644
index 00000000..356d1070
--- /dev/null
+++ b/res/layout-sw720dp/theme_view.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<com.cyanogenmod.filemanager.ui.preferences.ThemeView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="1dp"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/theme_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:gravity="center"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:textAppearance="@style/primary_text_appearance" />
+
+ <TextView
+ android:id="@+id/theme_author"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/theme_name"
+ android:gravity="center"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:textAppearance="@style/primary_text_appearance_nohighlight" />
+
+ <TextView
+ android:id="@+id/theme_desc"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:gravity="center"
+ android:ellipsize="end"
+ android:singleLine="false"
+ android:maxLines="2"
+ android:textAppearance="@style/secondary_text_appearance" />
+
+ <ImageView
+ android:id="@+id/theme_preview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_above="@id/theme_desc"
+ android:layout_below="@id/theme_author"
+ android:padding="@dimen/extra_large_margin"
+ android:layout_gravity="center"
+ android:scaleType="centerInside"
+ android:contentDescription="@null" />
+
+</com.cyanogenmod.filemanager.ui.preferences.ThemeView>
diff --git a/res/layout/bookmarks_item.xml b/res/layout/bookmarks_item.xml
index f1c7acca..fc8e4be5 100644
--- a/res/layout/bookmarks_item.xml
+++ b/res/layout/bookmarks_item.xml
@@ -17,7 +17,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="@dimen/default_row_height"
- android:background="@drawable/holo_selector" >
+ android:background="@drawable/holo_list_selector_deselected" >
<ImageView
android:id="@+id/bookmarks_item_icon"
diff --git a/res/layout/editor.xml b/res/layout/editor.xml
index af78d622..177d377e 100644
--- a/res/layout/editor.xml
+++ b/res/layout/editor.xml
@@ -46,6 +46,7 @@
android:gravity="top|left"
android:cursorVisible="true"
android:background="@null"
+ android:imeOptions="actionDone|flagNoFullscreen"
android:inputType="textMultiLine|textImeMultiLine"
android:text="@null"
android:textAppearance="@style/secondary_text_appearance" />
diff --git a/res/layout/history_item.xml b/res/layout/history_item.xml
index 4fca6ff1..2ef5fe97 100644
--- a/res/layout/history_item.xml
+++ b/res/layout/history_item.xml
@@ -17,7 +17,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="@dimen/default_row_height"
- android:background="@drawable/holo_selector" >
+ android:background="@drawable/holo_list_selector_deselected" >
<ImageView
android:id="@+id/history_item_icon"
diff --git a/res/layout/inline_autocomplete.xml b/res/layout/inline_autocomplete.xml
index 3938cb40..e6d1c518 100644
--- a/res/layout/inline_autocomplete.xml
+++ b/res/layout/inline_autocomplete.xml
@@ -27,6 +27,7 @@
android:gravity="top"
android:hint="@null"
android:inputType="none"
+ android:imeOptions="actionDone|flagNoFullscreen"
android:paddingLeft="@dimen/small_buttom_width"
android:singleLine="false"
android:textColor="@android:color/darker_gray"
@@ -46,7 +47,7 @@
android:gravity="top"
android:hint="@null"
android:inputType="textNoSuggestions|textImeMultiLine"
- android:imeOptions="actionDone"
+ android:imeOptions="actionDone|flagNoFullscreen"
android:paddingLeft="@dimen/small_buttom_width"
android:singleLine="false"
android:textColor="@color/black_transparent"
diff --git a/res/layout/input_name_dialog.xml b/res/layout/input_name_dialog.xml
index 3ff195f2..2ec64d78 100644
--- a/res/layout/input_name_dialog.xml
+++ b/res/layout/input_name_dialog.xml
@@ -40,7 +40,7 @@
android:layout_marginLeft="@dimen/extra_large_margin"
android:layout_marginRight="@dimen/extra_large_margin"
android:ems="@integer/default_edit_text_ems"
- android:imeOptions="actionDone"
+ android:imeOptions="actionDone|flagNoFullscreen"
android:scrollHorizontally="true"
android:selectAllOnFocus="true"
android:inputType="textNoSuggestions">
diff --git a/res/layout/navigation.xml b/res/layout/navigation.xml
index f77033c7..68df9c4f 100644
--- a/res/layout/navigation.xml
+++ b/res/layout/navigation.xml
@@ -17,6 +17,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:filemanager="http://schemas.android.com/apk/res/com.cyanogenmod.filemanager"
+ android:id="@+id/navigation_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 40f2ada4..757534b0 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -85,7 +85,7 @@
<string name="cm_filemanager_show_symlinks">Ver accesos directos</string>
<string name="filesystem_info_warning_title">Sin información</string>
<string name="filesystem_info_warning_msg">No hay información disponible para el sistema de archivos.</string>
- <string name="filesystem_info_cant_be_mounted_msg">El sistema de archivos no ha podido ser montado/desmontado.</string>
+ <string name="filesystem_info_cant_be_mounted_msg">El sistema de archivos no puede ser montado/desmontado.</string>
<string name="filesystem_info_mount_not_allowed_msg">La operación de montaje del sistema de archivos no está permitida en modo seguro. Tocar aquí para cambiar a modo superusuario.</string>
<string name="filesystem_info_mount_failed_msg">La operación de montaje del sistema de archivos ha fallado. Algunos sistemas de archivos, como las tarjetas SD, no pueden ser montados o desmontados porque están diseñados como sistemas de solo-lectura.</string>
<string name="filesystem_info_dialog_title">Información del sistema de archivos</string>
@@ -281,7 +281,7 @@
<string name="pref_about_summary">File Manager v<xliff:g id="version">%1$s</xliff:g>
\nCopyright \u00A9 2012 The CyanogenMod Project</string>
<string name="pref_general_behaviour_category">General</string>
- <string name="pref_case_sensitive_sort">Distinción mayúsc. y minúsc.</string>
+ <string name="pref_case_sensitive_sort">Ordenación sensible</string>
<string name="pref_disk_usage_warning_level">Aviso de uso de disco</string>
<string name="pref_disk_usage_warning_level_summary" formatted="false">Mostrar un color diferente para los widgets de uso de disco, cuando el espacio ocupado supere el <xliff:g id="level">%1$s</xliff:g> por ciento del total</string>
<string name="pref_compute_folder_statistics">Estadísticas de carpetas</string>
@@ -297,7 +297,7 @@
<string name="pref_access_mode_root">Modo superusuario</string>
<string name="pref_access_mode_root_summary">Modo superusuario\n\n¡Aviso! Este modo permite operaciones que pueden bloquear el dispositivo. Será su responsabilidad asegurarse de que la operación sea segura</string>
<string name="pref_search_results_category">Resultados</string>
- <string name="pref_show_relevance_widget">Mostrar widget de relevancia</string>
+ <string name="pref_show_relevance_widget">Mostrar relevancia</string>
<string name="pref_highlight_terms">Resaltar términos de búsqueda</string>
<string name="pref_sort_search_results_mode">Ordenación de resultados</string>
<string name="pref_sort_search_results_mode_none">Sin ordenar</string>
@@ -315,7 +315,7 @@
<string name="pref_themes_no_preview">Vista previa\nno disponible</string>
<string name="pref_themes_confirmation">Tema aplicado satisfactoriamente.</string>
<string name="pref_themes_not_found">Tema no encontrado.</string>
- <string name="pref_debug_traces">Habilitar registro de depuración</string>
+ <string name="pref_debug_traces">Habilitar depuración</string>
<string name="theme_default_name">Tema claro</string>
<string name="theme_default_description">Un tema en colores claros para File Manager.</string>
<string name="security_warning_extract">¡Aviso!\n\nExtraer archivos comprimidos que contienen rutas absolutas o relativas puede causar daños en su dispositivo por la posible sobrescritura de archivos de sistema.\n\n¿Continuar?</string>
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index 0278d310..fe85edb3 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -106,7 +106,8 @@
<!-- Theme button min width -->
<dimen name="themes_min_width_button">300dp</dimen>
- <!-- Theme width -->
+ <!-- Theme width/height -->
<dimen name="theme_max_width">300dip</dimen>
+ <dimen name="theme_max_height">600dip</dimen>
</resources>
diff --git a/res/values/overlay.xml b/res/values/overlay.xml
index 1a68d534..8d591964 100644
--- a/res/values/overlay.xml
+++ b/res/values/overlay.xml
@@ -60,6 +60,7 @@
/system/xbin/gunzip,
/system/xbin/pwd,
/system/xbin/readlink,
+ /system/xbin/stat,
/system/xbin/su,
/system/xbin/tar,
/system/xbin/uncompress,
diff --git a/res/xml/command_list.xml b/res/xml/command_list.xml
index caa288ac..c473c284 100644
--- a/res/xml/command_list.xml
+++ b/res/xml/command_list.xml
@@ -31,9 +31,9 @@
-->
<CommandList xmlns="http://schemas.android.com/apk/res/com.cyanogenmod.filemanager">
<!-- Start code (append to commands; for retrieve the exit code) -->
- <startcode commandId="startcode" commandPath="/system/xbin/echo %1$s0%2$s ; " />
+ <startcode commandId="startcode" commandPath="/system/xbin/echo -n %1$s0%2$s ; " />
<!-- Exit code (append to commands; for retrieve the exit code) -->
- <exitcode commandId="exitcode" commandPath=" ; /system/xbin/echo %1$s$?%2$s" />
+ <exitcode commandId="exitcode" commandPath=" ; /system/xbin/echo -n %1$s$?%2$s" />
<!-- Shell commands -->
<command commandId="bash" commandPath="/system/bin/sh" commandArgs="" />
@@ -49,14 +49,14 @@
<!-- FileSystem -->
<command commandId="mount" commandPath="/system/bin/mount" commandArgs="-o %1$s,remount -t auto %2$s %3$s" />
- <command commandId="mountpointinfo" commandPath="/system/bin/cat" commandArgs="/proc/mounts" />
+ <command commandId="mountpointinfo" commandPath="/system/bin/mount" commandArgs="" />
<!-- List/Find/Info -->
- <command commandId="ls" commandPath="cd" commandArgs="%1$s &amp;&amp; /system/bin/ls -al %1$s | { /system/xbin/grep -v -e '^l' || true; } &amp;&amp; /system/xbin/echo '>SIMLINKS>' &amp;&amp; /system/bin/ls -al %1$s | { /system/xbin/grep -e '^l' || true; } &amp;&amp; /system/xbin/echo '>SIMLINKS_DATA>' &amp;&amp; /system/bin/ls -aF %1$s | /system/xbin/grep -e '^l' | /system/xbin/cut -d ' ' -f2- &amp;&amp; /system/bin/ls -aF %1$s | /system/xbin/grep -e '^l' | /system/xbin/cut -d ' ' -f2- | /system/xbin/awk '{print &quot;\\&quot;&quot;$0&quot;\\&quot;&quot;}' | /system/xbin/xargs -r -n1 /system/xbin/readlink -f &amp;&amp; /system/bin/ls -F %1$s | /system/xbin/grep -e '^l' | /system/xbin/cut -d ' ' -f2- | /system/xbin/awk '{print &quot;\\&quot;&quot;$0&quot;\\&quot;&quot;}' | /system/xbin/xargs -r -n1 /system/xbin/readlink -f | /system/xbin/awk '{print &quot;\\&quot;&quot;$0&quot;\\&quot;&quot;}' | { /system/xbin/xargs -r /system/bin/ls -ald || /system/xbin/echo; }" />
- <command commandId="fileinfo" commandPath="/system/bin/ls" commandArgs="-ald %1$s" />
- <command commandId="find" commandPath="/system/xbin/find" commandArgs="%1$s \\( -name %2$s -o -name %3$s -o -name %4$s -o -name %5$s -o -name %6$s \\) -exec /system/xbin/echo {} \\; -exec /system/bin/ls -ald {} \\;" />
+ <command commandId="ls" commandPath="/system/bin/ls" commandArgs="%1$s 1&gt; /dev/null &amp;&amp; /system/xbin/stat -t %1$s* 2&gt;&amp;1" />
+ <command commandId="fileinfo" commandPath="/system/xbin/stat" commandArgs="-t %1$s 2&gt;&amp;1" />
+ <command commandId="find" commandPath="/system/xbin/find" commandArgs="%1$s \\( -name %2$s -o -name %3$s -o -name %4$s -o -name %5$s -o -name %6$s \\) -exec /system/xbin/stat -t {} 2&gt;&amp;1 \\;" />
<command commandId="quickfoldersearch" commandPath="/system/bin/ls" commandArgs="-aFd %1$s.* %1$s* 2&gt; /dev/null | /system/xbin/grep -e '^d' -e '^ld' | /system/xbin/cut -d&quot; &quot; -f2-" />
- <command commandId="readlink" commandPath="cd" commandArgs="%2$s &amp;&amp; /system/xbin/readlink -f %1$s | /system/xbin/awk -F// '{print &quot;\\&quot;&quot;$1&quot;\\&quot;&quot;}' | /system/xbin/xargs -n1 /system/xbin/dirname &amp;&amp; /system/xbin/readlink -f %1$s | /system/xbin/awk -F// '{print &quot;\\&quot;&quot;$1&quot;\\&quot;&quot;}' | /system/xbin/xargs -n1 /system/bin/ls -ald" />
+ <command commandId="readlink" commandPath="/system/bin/ls" commandArgs="%1$s 1&gt; /dev/null &amp;&amp; /system/xbin/stat -tL %1$s 2&gt;&amp;1" />
<!-- Operational -->
<command commandId="chmod" commandPath="/system/bin/chmod" commandArgs="%1$s %2$s" />
@@ -71,7 +71,7 @@
<!-- Usage -->
<command commandId="diskusage" commandPath="/system/bin/df" commandArgs="%1$s" />
<command commandId="diskusageall" commandPath="/system/bin/df" commandArgs="" />
- <command commandId="folderusage" commandPath="/system/bin/ls" commandArgs="-alR %1$s" />
+ <command commandId="folderusage" commandPath="/system/bin/ls" commandArgs="-alR %1$s 2&gt; /dev/null" />
<!-- I/O -->
<command commandId="read" commandPath="/system/bin/cat" commandArgs="%1$s" />
diff --git a/src/com/cyanogenmod/filemanager/FileManagerApplication.java b/src/com/cyanogenmod/filemanager/FileManagerApplication.java
index c765ee35..cc1ff941 100644
--- a/src/com/cyanogenmod/filemanager/FileManagerApplication.java
+++ b/src/com/cyanogenmod/filemanager/FileManagerApplication.java
@@ -35,6 +35,7 @@ import com.cyanogenmod.filemanager.preferences.ObjectStringIdentifier;
import com.cyanogenmod.filemanager.preferences.Preferences;
import com.cyanogenmod.filemanager.ui.ThemeManager;
import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
+import com.cyanogenmod.filemanager.util.AIDHelper;
import com.cyanogenmod.filemanager.util.FileHelper;
import com.cyanogenmod.filemanager.util.MimeTypeHelper;
@@ -100,7 +101,7 @@ public final class FileManagerApplication extends Application {
}
};
- // A broadcast receiver for detect the uninstall of apk with themes
+ // A broadcast receiver for detect the install/uninstall of apps (for themes, AIDs, ...)
private final BroadcastReceiver mUninstallReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -109,34 +110,46 @@ public final class FileManagerApplication extends Application {
intent.getAction().compareTo(Intent.ACTION_PACKAGE_FULLY_REMOVED) == 0) {
// Check that the remove package is not the current theme
if (intent.getData() != null) {
- // Get the package name and remove the schema
- String apkPackage = intent.getData().toString();
- apkPackage = apkPackage.substring("package:".length()); //$NON-NLS-1$
-
- Theme currentTheme = ThemeManager.getCurrentTheme(context);
- if (currentTheme.getPackage().compareTo(apkPackage) == 0) {
- // The apk that contains the current theme was remove, change
- // to default theme
- String composedId =
- (String)FileManagerSettings.SETTINGS_THEME.getDefaultValue();
- ThemeManager.setCurrentTheme(getApplicationContext(), composedId);
- try {
- Preferences.savePreference(
- FileManagerSettings.SETTINGS_THEME, composedId, true);
- } catch (Throwable ex) {
- Log.w(TAG, "can't save theme preference", ex); //$NON-NLS-1$
- }
+ // --- AIDs
+ try {
+ AIDHelper.getAIDs(getApplicationContext(), true);
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to reload AIDs", e); //$NON-NLS-1$
+ }
- // Notify the changes to activities
- try {
- Intent broadcastIntent =
- new Intent(FileManagerSettings.INTENT_THEME_CHANGED);
- broadcastIntent.putExtra(
- FileManagerSettings.EXTRA_THEME_ID, composedId);
- sendBroadcast(broadcastIntent);
- } catch (Throwable ex) {
- Log.w(TAG, "notify of theme change failed", ex); //$NON-NLS-1$
+ // --- Themes
+ try {
+ // Get the package name and remove the schema
+ String apkPackage = intent.getData().toString();
+ apkPackage = apkPackage.substring("package:".length()); //$NON-NLS-1$
+
+ Theme currentTheme = ThemeManager.getCurrentTheme(context);
+ if (currentTheme.getPackage().compareTo(apkPackage) == 0) {
+ // The apk that contains the current theme was remove, change
+ // to default theme
+ String composedId =
+ (String)FileManagerSettings.SETTINGS_THEME.getDefaultValue();
+ ThemeManager.setCurrentTheme(getApplicationContext(), composedId);
+ try {
+ Preferences.savePreference(
+ FileManagerSettings.SETTINGS_THEME, composedId, true);
+ } catch (Throwable ex) {
+ Log.w(TAG, "can't save theme preference", ex); //$NON-NLS-1$
+ }
+
+ // Notify the changes to activities
+ try {
+ Intent broadcastIntent =
+ new Intent(FileManagerSettings.INTENT_THEME_CHANGED);
+ broadcastIntent.putExtra(
+ FileManagerSettings.EXTRA_THEME_ID, composedId);
+ sendBroadcast(broadcastIntent);
+ } catch (Throwable ex) {
+ Log.w(TAG, "notify of theme change failed", ex); //$NON-NLS-1$
+ }
}
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to reload themes", e); //$NON-NLS-1$
}
}
}
@@ -153,8 +166,8 @@ public final class FileManagerApplication extends Application {
if (DEBUG) {
Log.d(TAG, "FileManagerApplication.onCreate"); //$NON-NLS-1$
}
- register();
init();
+ register();
}
/**
@@ -192,19 +205,6 @@ public final class FileManagerApplication extends Application {
* Method that register the application context.
*/
private void register() {
- //Save the static application reference
- sApp = this;
-
- // Read the system properties
- sSystemProperties = new Properties();
- readSystemProperties();
-
- // Check if the application is debuggable
- sIsDebuggable = (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE));
-
- // Check if the device is rooted
- sIsDeviceRooted = areShellCommandsPresent();
-
// Register the notify broadcast receiver
IntentFilter filter = new IntentFilter();
filter.addAction(FileManagerSettings.INTENT_SETTING_CHANGED);
@@ -222,10 +222,26 @@ public final class FileManagerApplication extends Application {
* Method that initializes the application.
*/
private void init() {
+ //Save the static application reference
+ sApp = this;
+
+ // Read the system properties
+ sSystemProperties = new Properties();
+ readSystemProperties();
+
+ // Check if the application is debuggable
+ sIsDebuggable = (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE));
+
+ // Check if the device is rooted
+ sIsDeviceRooted = areShellCommandsPresent();
+
//Sets the default preferences if no value is set yet
FileHelper.ROOT_DIRECTORY = getString(R.string.root_dir);
Preferences.loadDefaults();
+ // Read AIDs
+ AIDHelper.getAIDs(getApplicationContext(), true);
+
// Allocate the default and current themes
String defaultValue = ((String)FileManagerSettings.
SETTINGS_THEME.getDefaultValue());
@@ -243,6 +259,9 @@ public final class FileManagerApplication extends Application {
Log.w(TAG, "can't save theme preference", ex); //$NON-NLS-1$
}
}
+ // Set the base theme
+ Theme theme = ThemeManager.getCurrentTheme(getApplicationContext());
+ theme.setBaseTheme(getApplicationContext(), false);
//Create a console for background tasks
allocBackgroundConsole(getApplicationContext());
diff --git a/src/com/cyanogenmod/filemanager/activities/BookmarksActivity.java b/src/com/cyanogenmod/filemanager/activities/BookmarksActivity.java
index d14988c8..317c8a4c 100644
--- a/src/com/cyanogenmod/filemanager/activities/BookmarksActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/BookmarksActivity.java
@@ -587,15 +587,22 @@ public class BookmarksActivity extends Activity implements OnItemClickListener,
private List<Bookmark> loadUserBookmarks() {
List<Bookmark> bookmarks = new ArrayList<Bookmark>();
Cursor cursor = Bookmarks.getAllBookmarks(this.getContentResolver());
- if (cursor != null && cursor.moveToFirst()) {
- do {
- Bookmark bm = new Bookmark(cursor);
- if (this.mChRooted && !StorageHelper.isPathInStorageVolume(bm.mPath)) {
- continue;
+ try {
+ if (cursor != null && cursor.moveToFirst()) {
+ do {
+ Bookmark bm = new Bookmark(cursor);
+ if (this.mChRooted && !StorageHelper.isPathInStorageVolume(bm.mPath)) {
+ continue;
+ }
+ bookmarks.add(bm);
+ } while (cursor.moveToNext());
+ }
+ } finally {
+ try {
+ if (cursor != null) {
+ cursor.close();
}
- bookmarks.add(bm);
- } while (cursor.moveToNext());
- cursor.close();
+ } catch (Exception e) {/**NON BLOCK**/}
}
return bookmarks;
}
diff --git a/src/com/cyanogenmod/filemanager/activities/EditorActivity.java b/src/com/cyanogenmod/filemanager/activities/EditorActivity.java
index 6b682ad2..4a922121 100644
--- a/src/com/cyanogenmod/filemanager/activities/EditorActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/EditorActivity.java
@@ -602,9 +602,9 @@ public class EditorActivity extends Activity implements TextWatcher {
}
} else {
// Now we have the buffer, set the text of the editor
- if (!EditorActivity.this.mBinary && EditorActivity.this.mFso.getSize() == 0) {
- // Clean the document
- EditorActivity.this.mEditor.setText(""); //$NON-NLS-1$
+ if (EditorActivity.this.mBinary) {
+ EditorActivity.this.mEditor.setText(
+ this.mReader.mBuffer, BufferType.NORMAL);
} else {
EditorActivity.this.mEditor.setText(
this.mReader.mBuffer, BufferType.EDITABLE);
diff --git a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java
index 56b7ec90..1ecd3be5 100644
--- a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java
@@ -617,9 +617,7 @@ public class NavigationActivity extends Activity
//Ensure initial is an absolute directory
try {
- initialDir =
- CommandHelper.getAbsolutePath(
- NavigationActivity.this, initialDir, null);
+ initialDir = new File(initialDir).getAbsolutePath();
} catch (Throwable e) {
Log.e(TAG, "Resolve of initital directory fails", e); //$NON-NLS-1$
String msg =
@@ -916,7 +914,7 @@ public class NavigationActivity extends Activity
* {@inheritDoc}
*/
@Override
- public void onRequestRefresh(Object o) {
+ public void onRequestRefresh(Object o, boolean clearSelection) {
if (o instanceof FileSystemObject) {
// Refresh only the item
this.getCurrentNavigationView().refresh((FileSystemObject)o);
@@ -924,14 +922,16 @@ public class NavigationActivity extends Activity
// Refresh all
getCurrentNavigationView().refresh();
}
- this.getCurrentNavigationView().onDeselectAll();
+ if (clearSelection) {
+ this.getCurrentNavigationView().onDeselectAll();
+ }
}
/**
* {@inheritDoc}
*/
@Override
- public void onRequestRemove(Object o) {
+ public void onRequestRemove(Object o, boolean clearSelection) {
if (o instanceof FileSystemObject) {
// Remove from view
this.getCurrentNavigationView().removeItem((FileSystemObject)o);
@@ -939,9 +939,11 @@ public class NavigationActivity extends Activity
//Remove from history
removeFromHistory((FileSystemObject)o);
} else {
- onRequestRefresh(null);
+ onRequestRefresh(null, clearSelection);
+ }
+ if (clearSelection) {
+ this.getCurrentNavigationView().onDeselectAll();
}
- this.getCurrentNavigationView().onDeselectAll();
}
/**
@@ -1187,7 +1189,6 @@ public class NavigationActivity extends Activity
bundle.putString(
SearchActivity.EXTRA_SEARCH_DIRECTORY,
getCurrentNavigationView().getCurrentDir());
- // TODO VoiceSearch icon is not shown. This must be a bug of CM. Verify with a test app.
startSearch(Preferences.getLastSearch(), true, bundle, false);
return true;
}
@@ -1596,10 +1597,13 @@ public class NavigationActivity extends Activity
Theme theme = ThemeManager.getCurrentTheme(this);
theme.setBaseTheme(this, false);
+ //- Layout
+ View v = findViewById(R.id.navigation_layout);
+ theme.setBackgroundDrawable(this, v, "background_drawable"); //$NON-NLS-1$
//- ActionBar
theme.setTitlebarDrawable(this, getActionBar(), "titlebar_drawable"); //$NON-NLS-1$
//- StatusBar
- View v = findViewById(R.id.navigation_statusbar);
+ v = findViewById(R.id.navigation_statusbar);
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
theme.setBackgroundDrawable(this, v, "titlebar_drawable"); //$NON-NLS-1$
} else {
diff --git a/src/com/cyanogenmod/filemanager/activities/SearchActivity.java b/src/com/cyanogenmod/filemanager/activities/SearchActivity.java
index 2c706fc6..60d043c8 100644
--- a/src/com/cyanogenmod/filemanager/activities/SearchActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/SearchActivity.java
@@ -54,6 +54,7 @@ import com.cyanogenmod.filemanager.adapters.SearchResultAdapter;
import com.cyanogenmod.filemanager.commands.AsyncResultExecutable;
import com.cyanogenmod.filemanager.commands.AsyncResultListener;
import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
+import com.cyanogenmod.filemanager.console.RelaunchableException;
import com.cyanogenmod.filemanager.listeners.OnRequestRefreshListener;
import com.cyanogenmod.filemanager.model.Directory;
import com.cyanogenmod.filemanager.model.FileSystemObject;
@@ -80,6 +81,7 @@ import com.cyanogenmod.filemanager.ui.widgets.FlingerListView.OnItemFlingerRespo
import com.cyanogenmod.filemanager.util.CommandHelper;
import com.cyanogenmod.filemanager.util.DialogHelper;
import com.cyanogenmod.filemanager.util.ExceptionUtil;
+import com.cyanogenmod.filemanager.util.ExceptionUtil.OnRelaunchCommandResult;
import com.cyanogenmod.filemanager.util.FileHelper;
import com.cyanogenmod.filemanager.util.StorageHelper;
@@ -868,15 +870,19 @@ public class SearchActivity extends Activity
FileSystemObject fso = result.getFso();
if (fso instanceof Directory) {
back(false, fso, false);
+ return;
} else if (fso instanceof Symlink) {
Symlink symlink = (Symlink)fso;
if (symlink.getLinkRef() != null && symlink.getLinkRef() instanceof Directory) {
back(false, symlink.getLinkRef(), false);
+ return;
}
- } else {
- // Open the file with the preferred registered app
- back(false, fso, false);
+ fso = symlink.getLinkRef();
}
+
+ // Open the file with the preferred registered app
+ back(false, fso, false);
+
} catch (Throwable ex) {
ExceptionUtil.translateException(this.mSearchListView.getContext(), ex);
}
@@ -955,7 +961,7 @@ public class SearchActivity extends Activity
* {@inheritDoc}
*/
@Override
- public void onRequestRefresh(Object o) {
+ public void onRequestRefresh(Object o, boolean clearSelection) {
// Refresh only the item
SearchResultAdapter adapter =
(SearchResultAdapter)this.mSearchListView.getAdapter();
@@ -985,7 +991,7 @@ public class SearchActivity extends Activity
* {@inheritDoc}
*/
@Override
- public void onRequestRemove(Object o) {
+ public void onRequestRemove(Object o, boolean clearSelection) {
if (o instanceof FileSystemObject) {
removeItem((FileSystemObject)o);
}
@@ -1006,10 +1012,14 @@ public class SearchActivity extends Activity
*
* @param cancelled Indicates if the activity was cancelled
* @param item The fso
+ * @param isChecked If the fso was fully retrieve previously to this call. Otherwise, a
+ * getFileInfo call is done to complete the fso information
* @hide
*/
void back(final boolean cancelled, FileSystemObject item, boolean isChecked) {
- Intent intent = new Intent();
+ final Context ctx = SearchActivity.this;
+ final Intent intent = new Intent();
+ boolean finish = true;
if (cancelled) {
if (SearchActivity.this.mDrawingSearchResultTask != null
&& SearchActivity.this.mDrawingSearchResultTask.isRunning()) {
@@ -1023,44 +1033,77 @@ public class SearchActivity extends Activity
setResult(RESULT_CANCELED, intent);
} else {
// Check that the bookmark exists
+ FileSystemObject fso = item;
try {
- FileSystemObject fso = item;
if (!isChecked) {
- fso = CommandHelper.getFileInfo(this, item.getFullPath(), null);
- }
- if (fso != null) {
- if (FileHelper.isDirectory(fso)) {
- intent.putExtra(NavigationActivity.EXTRA_SEARCH_ENTRY_SELECTION, fso);
- intent.putExtra(
- NavigationActivity.EXTRA_SEARCH_LAST_SEARCH_DATA,
- (Parcelable)createSearchInfo());
- setResult(RESULT_OK, intent);
- } else {
- // Open the file here, so when focus back to the app, the search activity
- // its in top of the stack
- IntentsActionPolicy.openFileSystemObject(this, fso, false, null, null);
- return;
- }
- } else {
- // The fso not exists, delete the fso from the search
- try {
- removeItem(item);
- } catch (Exception ex) {/**NON BLOCK**/}
+ fso = CommandHelper.getFileInfo(ctx, item.getFullPath(), null);
}
+ finish = navigateTo(fso, intent);
} catch (Exception e) {
// Capture the exception
- ExceptionUtil.translateException(this, e);
- if (e instanceof NoSuchFileOrDirectory || e instanceof FileNotFoundException) {
- // The fso not exists, delete the fso from the search
- try {
- removeItem(item);
- } catch (Exception ex) {/**NON BLOCK**/}
+ final FileSystemObject fFso = fso;
+ final OnRelaunchCommandResult relaunchListener = new OnRelaunchCommandResult() {
+ @Override
+ public void onSuccess() {
+ if (navigateTo(fFso, intent)) {
+ finish();
+ }
+ }
+ @Override
+ public void onFailed(Throwable cause) {
+ ExceptionUtil.translateException(ctx, cause, false, false);
+ }
+ @Override
+ public void onCancelled() { /** NON BLOCK**/}
+ };
+ ExceptionUtil.translateException(ctx, e, false, true, relaunchListener);
+ if (!(e instanceof RelaunchableException)) {
+ if (e instanceof NoSuchFileOrDirectory || e instanceof FileNotFoundException) {
+ // The fso not exists, delete the fso from the search
+ try {
+ removeItem(fso);
+ } catch (Exception ex) {/**NON BLOCK**/}
+ }
}
return;
}
}
- finish();
+
+ // End this activity
+ if (finish) {
+ finish();
+ }
+ }
+
+ /**
+ * Method that navigate to the file system used the intent (NavigationActivity)
+ *
+ * @param fso The file system object to navigate to
+ * @param intent The intent used to navigate to
+ * @return boolean If the action implies finish this activity
+ */
+ boolean navigateTo(FileSystemObject fso, Intent intent) {
+ if (fso != null) {
+ if (FileHelper.isDirectory(fso)) {
+ intent.putExtra(NavigationActivity.EXTRA_SEARCH_ENTRY_SELECTION, fso);
+ intent.putExtra(
+ NavigationActivity.EXTRA_SEARCH_LAST_SEARCH_DATA,
+ (Parcelable)createSearchInfo());
+ setResult(RESULT_OK, intent);
+ return true;
+ }
+
+ // Open the file here, so when focus back to the app, the search activity
+ // its in top of the stack
+ IntentsActionPolicy.openFileSystemObject(this, fso, false, null, null);
+ } else {
+ // The fso not exists, delete the fso from the search
+ try {
+ removeItem(fso);
+ } catch (Exception ex) {/**NON BLOCK**/}
+ }
+ return false;
}
/**
diff --git a/src/com/cyanogenmod/filemanager/adapters/AssociationsAdapter.java b/src/com/cyanogenmod/filemanager/adapters/AssociationsAdapter.java
index 1daaf715..22f6c3c9 100644
--- a/src/com/cyanogenmod/filemanager/adapters/AssociationsAdapter.java
+++ b/src/com/cyanogenmod/filemanager/adapters/AssociationsAdapter.java
@@ -95,7 +95,7 @@ public class AssociationsAdapter
this.mOnItemClickListener = onItemClickListener;
//Do cache of the data for better performance
- processData();
+ processData(intents);
}
/**
@@ -103,7 +103,7 @@ public class AssociationsAdapter
*/
@Override
public void notifyDataSetChanged() {
- processData();
+ processData(null);
super.notifyDataSetChanged();
}
@@ -117,13 +117,15 @@ public class AssociationsAdapter
/**
* Method that process the data before use {@link #getView} method.
+ *
+ * @param intents The list of intents (to better performance) or null.
*/
- private void processData() {
+ private void processData(List<ResolveInfo> intents) {
this.mData = new DataHolder[getCount()];
- int cc = getCount();
+ int cc = (intents == null) ? getCount() : intents.size();
for (int i = 0; i < cc; i++) {
//Intent info
- ResolveInfo intentInfo = getItem(i);
+ ResolveInfo intentInfo = (intents == null) ? getItem(i) : intents.get(i);
//Build the data holder
this.mData[i] = new AssociationsAdapter.DataHolder();
diff --git a/src/com/cyanogenmod/filemanager/adapters/BookmarksAdapter.java b/src/com/cyanogenmod/filemanager/adapters/BookmarksAdapter.java
index a60ccd3b..cbe63a49 100644
--- a/src/com/cyanogenmod/filemanager/adapters/BookmarksAdapter.java
+++ b/src/com/cyanogenmod/filemanager/adapters/BookmarksAdapter.java
@@ -108,7 +108,7 @@ public class BookmarksAdapter extends ArrayAdapter<Bookmark> {
this.mOnActionClickListener = onActionClickListener;
//Do cache of the data for better performance
- processData();
+ processData(bookmarks);
}
/**
@@ -116,7 +116,7 @@ public class BookmarksAdapter extends ArrayAdapter<Bookmark> {
*/
@Override
public void notifyDataSetChanged() {
- processData();
+ processData(null);
super.notifyDataSetChanged();
}
@@ -131,13 +131,15 @@ public class BookmarksAdapter extends ArrayAdapter<Bookmark> {
/**
* Method that process the data before use {@link #getView} method.
+ *
+ * @param bookmarks The list of bookmarks (to better performance) or null.
*/
- private void processData() {
+ private void processData(List<Bookmark> bookmarks) {
this.mData = new DataHolder[getCount()];
- int cc = getCount();
+ int cc = (bookmarks == null) ? getCount() : bookmarks.size();
for (int i = 0; i < cc; i++) {
//Bookmark info
- Bookmark bookmark = getItem(i);
+ Bookmark bookmark = (bookmarks == null) ? getItem(i) : bookmarks.get(i);
//Build the data holder
this.mData[i] = new BookmarksAdapter.DataHolder();
@@ -187,7 +189,7 @@ public class BookmarksAdapter extends ArrayAdapter<Bookmark> {
// Apply the current theme
Theme theme = ThemeManager.getCurrentTheme(getContext());
theme.setBackgroundDrawable(
- getContext(), v, "background_drawable"); //$NON-NLS-1$
+ getContext(), v, "selectors_deselected_drawable"); //$NON-NLS-1$
theme.setTextColor(
getContext(), viewHolder.mTvName, "text_color"); //$NON-NLS-1$
theme.setTextColor(
diff --git a/src/com/cyanogenmod/filemanager/adapters/CheckableListAdapter.java b/src/com/cyanogenmod/filemanager/adapters/CheckableListAdapter.java
index befac79b..be28711f 100644
--- a/src/com/cyanogenmod/filemanager/adapters/CheckableListAdapter.java
+++ b/src/com/cyanogenmod/filemanager/adapters/CheckableListAdapter.java
@@ -176,8 +176,8 @@ public class CheckableListAdapter extends ArrayAdapter<CheckableListAdapter.Chec
int cc = getCount();
for (int i = 0; i < cc; i++) {
getItem(i).mChecked = (i == position);
- notifyDataSetChanged();
}
+ notifyDataSetChanged();
}
}
diff --git a/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java b/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java
index c0f5facb..740dde41 100644
--- a/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java
+++ b/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java
@@ -135,7 +135,7 @@ public class FileSystemObjectAdapter
//Do cache of the data for better performance
loadDefaultIcons();
- processData();
+ processData(files);
}
/**
@@ -161,7 +161,7 @@ public class FileSystemObjectAdapter
*/
@Override
public void notifyDataSetChanged() {
- processData();
+ processData(null);
super.notifyDataSetChanged();
}
@@ -195,16 +195,18 @@ public class FileSystemObjectAdapter
/**
* Method that process the data before use {@link #getView} method.
+ *
+ * @param files The list of files (to better performance) or null.
*/
- private void processData() {
+ private void processData(List<FileSystemObject> files) {
Theme theme = ThemeManager.getCurrentTheme(getContext());
Resources res = getContext().getResources();
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
this.mData = new DataHolder[getCount()];
- int cc = getCount();
+ int cc = (files == null) ? getCount() : files.size();
for (int i = 0; i < cc; i++) {
//File system object info
- FileSystemObject fso = getItem(i);
+ FileSystemObject fso = (files == null) ? getItem(i) : files.get(i);
//Parse the last modification time and permissions
StringBuilder sbSummary = new StringBuilder();
@@ -213,7 +215,7 @@ public class FileSystemObjectAdapter
} else {
sbSummary.append(df.format(fso.getLastModifiedTime()));
sbSummary.append(" "); //$NON-NLS-1$
- sbSummary.append(fso.toRawString());
+ sbSummary.append(fso.toRawPermissionString());
}
//Build the data holder
@@ -457,7 +459,6 @@ public class FileSystemObjectAdapter
theme.getDrawable(
getContext(), "checkbox_deselected_drawable"); //$NON-NLS-1$
}
- notifyDataSetChanged();
//Add or remove from the global selected items
FileSystemObject fso = getItem(i);
@@ -477,6 +478,9 @@ public class FileSystemObjectAdapter
FileSystemObjectAdapter.this.mSelectedItems);
this.mOnSelectionChangedListener.onSelectionChanged(selection);
}
+
+ // The internal structure was update, only super adapter need to be notified
+ super.notifyDataSetChanged();
}
}
diff --git a/src/com/cyanogenmod/filemanager/adapters/HistoryAdapter.java b/src/com/cyanogenmod/filemanager/adapters/HistoryAdapter.java
index 0a604ca6..4582410f 100644
--- a/src/com/cyanogenmod/filemanager/adapters/HistoryAdapter.java
+++ b/src/com/cyanogenmod/filemanager/adapters/HistoryAdapter.java
@@ -101,7 +101,7 @@ public class HistoryAdapter extends ArrayAdapter<History> {
this.mIconHolder = new IconHolder();
//Do cache of the data for better performance
- processData();
+ processData(history);
}
/**
@@ -109,7 +109,7 @@ public class HistoryAdapter extends ArrayAdapter<History> {
*/
@Override
public void notifyDataSetChanged() {
- processData();
+ processData(null);
super.notifyDataSetChanged();
}
@@ -123,14 +123,16 @@ public class HistoryAdapter extends ArrayAdapter<History> {
}
/**
- * Method that process the data before use {@link #getView} method .
+ * Method that process the data before use {@link #getView} method.
+ *
+ * @param historyData The list of histories (to better performance) or null.
*/
- private void processData() {
+ private void processData(List<History> historyData) {
this.mData = new DataHolder[getCount()];
- int cc = getCount();
+ int cc = (historyData == null) ? getCount() : historyData.size();
for (int i = 0; i < cc; i++) {
//History info
- History history = getItem(i);
+ History history = (historyData == null) ? getItem(i) : historyData.get(i);
//Build the data holder
this.mData[i] = new HistoryAdapter.DataHolder();
@@ -176,7 +178,7 @@ public class HistoryAdapter extends ArrayAdapter<History> {
// Apply the current theme
Theme theme = ThemeManager.getCurrentTheme(getContext());
theme.setBackgroundDrawable(
- getContext(), v, "background_drawable"); //$NON-NLS-1$
+ getContext(), v, "selectors_deselected_drawable"); //$NON-NLS-1$
theme.setTextColor(
getContext(), viewHolder.mTvName, "text_color"); //$NON-NLS-1$
theme.setTextColor(
diff --git a/src/com/cyanogenmod/filemanager/adapters/SearchResultAdapter.java b/src/com/cyanogenmod/filemanager/adapters/SearchResultAdapter.java
index 7a8027e9..0561a647 100644
--- a/src/com/cyanogenmod/filemanager/adapters/SearchResultAdapter.java
+++ b/src/com/cyanogenmod/filemanager/adapters/SearchResultAdapter.java
@@ -127,7 +127,7 @@ public class SearchResultAdapter extends ArrayAdapter<SearchResult> {
//Do cache of the data for better performance
loadDefaultIcons();
- processData();
+ processData(files);
}
/**
@@ -143,7 +143,7 @@ public class SearchResultAdapter extends ArrayAdapter<SearchResult> {
*/
@Override
public void notifyDataSetChanged() {
- processData();
+ processData(null);
super.notifyDataSetChanged();
}
@@ -158,17 +158,19 @@ public class SearchResultAdapter extends ArrayAdapter<SearchResult> {
/**
* Method that process the data before use {@link #getView} method.
+ *
+ * @param files The list of files (to better performance) or null.
*/
- private void processData() {
+ private void processData(List<SearchResult> files) {
Theme theme = ThemeManager.getCurrentTheme(getContext());
int highlightedColor =
theme.getColor(getContext(), "search_highlight_color"); //$NON-NLS-1$
this.mData = new DataHolder[getCount()];
- int cc = getCount();
+ int cc = (files == null) ? getCount() : files.size();
for (int i = 0; i < cc; i++) {
//File system object info
- SearchResult result = getItem(i);
+ SearchResult result = (files == null) ? getItem(i) : files.get(i);
//Build the data holder
this.mData[i] = new SearchResultAdapter.DataHolder();
diff --git a/src/com/cyanogenmod/filemanager/commands/ExecutableCreator.java b/src/com/cyanogenmod/filemanager/commands/ExecutableCreator.java
index 630546f8..a0fd6f94 100644
--- a/src/com/cyanogenmod/filemanager/commands/ExecutableCreator.java
+++ b/src/com/cyanogenmod/filemanager/commands/ExecutableCreator.java
@@ -18,6 +18,8 @@ package com.cyanogenmod.filemanager.commands;
import com.cyanogenmod.filemanager.commands.ListExecutable.LIST_MODE;
import com.cyanogenmod.filemanager.console.CommandNotFoundException;
+import com.cyanogenmod.filemanager.console.InsufficientPermissionsException;
+import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
import com.cyanogenmod.filemanager.model.Group;
import com.cyanogenmod.filemanager.model.MountPoint;
import com.cyanogenmod.filemanager.model.Permissions;
@@ -37,9 +39,12 @@ public interface ExecutableCreator {
* @return ChangeCurrentDirExecutable A {@link ChangeCurrentDirExecutable} executable
* implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
ChangeCurrentDirExecutable createChangeCurrentDirExecutable(
- String dir) throws CommandNotFoundException;
+ String dir) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for change the owner of a file system object.
@@ -50,9 +55,12 @@ public interface ExecutableCreator {
* @return ChangeOwnerExecutable A {@link ChangeOwnerExecutable} executable
* implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
ChangeOwnerExecutable createChangeOwnerExecutable(
- String fso, User newUser, Group newGroup) throws CommandNotFoundException;
+ String fso, User newUser, Group newGroup) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for change the permissions of a file system object.
@@ -62,9 +70,12 @@ public interface ExecutableCreator {
* @return ChangePermissionsExecutable A {@link ChangePermissionsExecutable} executable
* implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
ChangePermissionsExecutable createChangePermissionsExecutable(
- String fso, Permissions newPermissions) throws CommandNotFoundException;
+ String fso, Permissions newPermissions) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for copy a file system object to
@@ -74,8 +85,11 @@ public interface ExecutableCreator {
* @param dst The absolute path to the destination file system object
* @return CopyExecutable A {@link CopyExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- CopyExecutable createCopyExecutable(String src, String dst) throws CommandNotFoundException;
+ CopyExecutable createCopyExecutable(String src, String dst) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for create a new directory.
@@ -84,9 +98,12 @@ public interface ExecutableCreator {
* @return CreateDirExecutable A {@link CreateDirExecutable} executable implementation
* reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
CreateDirExecutable createCreateDirectoryExecutable(String dir)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for create a new file.
@@ -95,8 +112,11 @@ public interface ExecutableCreator {
* @return CreateFileExecutable A {@link CreateFileExecutable} executable
* implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- CreateFileExecutable createCreateFileExecutable(String file) throws CommandNotFoundException;
+ CreateFileExecutable createCreateFileExecutable(String file) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve the current directory.
@@ -104,8 +124,11 @@ public interface ExecutableCreator {
* @return CurrentDirExecutable A {@link CurrentDirExecutable} executable
* implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- CurrentDirExecutable createCurrentDirExecutable() throws CommandNotFoundException;
+ CurrentDirExecutable createCurrentDirExecutable() throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for delete a directory.
@@ -114,8 +137,11 @@ public interface ExecutableCreator {
* @return DeleteDirExecutable A {@link DeleteDirExecutable} executable implementation
* reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- DeleteDirExecutable createDeleteDirExecutable(String dir) throws CommandNotFoundException;
+ DeleteDirExecutable createDeleteDirExecutable(String dir) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for delete a file.
@@ -124,8 +150,11 @@ public interface ExecutableCreator {
* @return DeleteFileExecutable A {@link DeleteFileExecutable} executable
* implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- DeleteFileExecutable createDeleteFileExecutable(String file) throws CommandNotFoundException;
+ DeleteFileExecutable createDeleteFileExecutable(String file) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve the disk usage.
@@ -134,8 +163,11 @@ public interface ExecutableCreator {
* @return DiskUsageExecutable A {@link DiskUsageExecutable} executable implementation
* reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- DiskUsageExecutable createDiskUsageExecutable() throws CommandNotFoundException;
+ DiskUsageExecutable createDiskUsageExecutable() throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve the disk usage.
@@ -145,8 +177,11 @@ public interface ExecutableCreator {
* @return DiskUsageExecutable A {@link DiskUsageExecutable} executable implementation
* reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- DiskUsageExecutable createDiskUsageExecutable(String dir) throws CommandNotFoundException;
+ DiskUsageExecutable createDiskUsageExecutable(String dir) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for expanding environment variables.
@@ -155,8 +190,11 @@ public interface ExecutableCreator {
* @param msg The message to expand
* @return EchoExecutable A {@link EchoExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- EchoExecutable createEchoExecutable(String msg) throws CommandNotFoundException;
+ EchoExecutable createEchoExecutable(String msg) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that execute a command
@@ -165,9 +203,12 @@ public interface ExecutableCreator {
* @param asyncResultListener The listener where to return partial results
* @return ExecExecutable A {@link ExecExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
ExecExecutable createExecExecutable(
- String cmd, AsyncResultListener asyncResultListener) throws CommandNotFoundException;
+ String cmd, AsyncResultListener asyncResultListener) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for make searches over the filesystem.
@@ -177,10 +218,13 @@ public interface ExecutableCreator {
* @param asyncResultListener The listener where to return partial results
* @return FindExecutable A {@link FindExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
FindExecutable createFindExecutable(
String directory, Query query, AsyncResultListener asyncResultListener)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for compute the disk usage of a folder.
@@ -190,27 +234,36 @@ public interface ExecutableCreator {
* @return FolderUsageExecutable A {@link FolderUsageExecutable} executable
* implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
FolderUsageExecutable createFolderUsageExecutable(
String directory, AsyncResultListener asyncResultListener)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve the groups of the current user.
*
* @return GroupsExecutable A {@link GroupsExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
GroupsExecutable createGroupsExecutable()
- throws com.cyanogenmod.filemanager.console.CommandNotFoundException;
+ throws com.cyanogenmod.filemanager.console.CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve identity information of the current user.
*
* @return IdentityExecutable A {@link IdentityExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- IdentityExecutable createIdentityExecutable() throws CommandNotFoundException;
+ IdentityExecutable createIdentityExecutable() throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates a symlink of an other file system object.
@@ -219,9 +272,12 @@ public interface ExecutableCreator {
* @param link The absolute path to the link fso
* @return LinkExecutable A {@link LinkExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
LinkExecutable createLinkExecutable(
- String src, String link) throws CommandNotFoundException;
+ String src, String link) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for list files of a directory.
@@ -229,10 +285,13 @@ public interface ExecutableCreator {
* @param src The directory where to do the listing
* @return ListExecutable A {@link ListExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
- * @see LIST_MODE
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
+ * @see LIST_MODE#DIRECTORY
*/
ListExecutable createListExecutable(String src)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve information of a file
@@ -241,10 +300,13 @@ public interface ExecutableCreator {
* @param followSymlinks If follow the symlink
* @return ListExecutable A {@link ListExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
- * @see LIST_MODE
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
+ * @see LIST_MODE#FILEINFO
*/
ListExecutable createFileInfoExecutable(String src, boolean followSymlinks)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve identity information of the current user.
@@ -253,9 +315,12 @@ public interface ExecutableCreator {
* @param rw Indicates if the operation mount the device as read-write
* @return MountExecutable A {@link MountExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
MountExecutable createMountExecutable(
- MountPoint mp, boolean rw) throws CommandNotFoundException;
+ MountPoint mp, boolean rw) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve identity information of the current user.
@@ -263,8 +328,11 @@ public interface ExecutableCreator {
* @return MountPointInfoExecutable A {@link MountPointInfoExecutable} executable
* implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- MountPointInfoExecutable createMountPointInfoExecutable() throws CommandNotFoundException;
+ MountPointInfoExecutable createMountPointInfoExecutable() throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for move a file system object to
@@ -274,8 +342,11 @@ public interface ExecutableCreator {
* @param dst The absolute path to the destination file system object
* @return MoveExecutable A {@link MoveExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- MoveExecutable createMoveExecutable(String src, String dst) throws CommandNotFoundException;
+ MoveExecutable createMoveExecutable(String src, String dst) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve the parent directory
@@ -285,8 +356,11 @@ public interface ExecutableCreator {
* @return ParentDirExecutable A {@link ParentDirExecutable} executable implementation
* reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- ParentDirExecutable createParentDirExecutable(String fso) throws CommandNotFoundException;
+ ParentDirExecutable createParentDirExecutable(String fso) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve operating system process identifier of a
@@ -295,8 +369,11 @@ public interface ExecutableCreator {
* @return ProcessIdExecutable A {@link ProcessIdExecutable} executable implementation
* reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- ProcessIdExecutable createShellProcessIdExecutable() throws CommandNotFoundException;
+ ProcessIdExecutable createShellProcessIdExecutable() throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for retrieve operating system process identifier of a
@@ -307,9 +384,12 @@ public interface ExecutableCreator {
* @return ProcessIdExecutable A {@link ProcessIdExecutable} executable implementation
* reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
ProcessIdExecutable createProcessIdExecutable(
- int pid, String processName) throws CommandNotFoundException;
+ int pid, String processName) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for quickly retrieve the name of directories
@@ -319,9 +399,12 @@ public interface ExecutableCreator {
* @return ProcessIdExecutable A {@link ProcessIdExecutable} executable implementation
* reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
QuickFolderSearchExecutable createQuickFolderSearchExecutable(
- String regexp) throws CommandNotFoundException;
+ String regexp) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for read data from disk.
@@ -330,10 +413,13 @@ public interface ExecutableCreator {
* @param asyncResultListener The listener where to return partial results
* @return ReadExecutable A {@link ReadExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
ReadExecutable createReadExecutable(
String file, AsyncResultListener asyncResultListener)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for resolves the real
@@ -343,8 +429,11 @@ public interface ExecutableCreator {
* @return ResolveLinkExecutable A {@link ResolveLinkExecutable} executable
* implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
- ResolveLinkExecutable createResolveLinkExecutable(String fso) throws CommandNotFoundException;
+ ResolveLinkExecutable createResolveLinkExecutable(String fso) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for send a signal to the current process.
@@ -353,9 +442,12 @@ public interface ExecutableCreator {
* @param signal The signal to send
* @return SendSignalExecutable A {@link SendSignalExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
SendSignalExecutable createSendSignalExecutable(
- int process, SIGNAL signal) throws CommandNotFoundException;
+ int process, SIGNAL signal) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for send a kill signal to the current process.
@@ -364,9 +456,12 @@ public interface ExecutableCreator {
* @param signal The signal to send
* @return SendSignalExecutable A {@link SendSignalExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
SendSignalExecutable createKillExecutable(
- int process) throws CommandNotFoundException;
+ int process) throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for write data to disk.
@@ -375,10 +470,13 @@ public interface ExecutableCreator {
* @param asyncResultListener The listener where to return partial results
* @return WriteExecutable A {@link WriteExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
WriteExecutable createWriteExecutable(
String file, AsyncResultListener asyncResultListener)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for archive-compress file system objects.
@@ -389,11 +487,14 @@ public interface ExecutableCreator {
* @param asyncResultListener The listener where to return partial results
* @return CompressExecutable A {@link CompressExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
CompressExecutable createCompressExecutable(
CompressionMode mode, String dst, String[] src,
AsyncResultListener asyncResultListener)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for compress a file system object.
@@ -403,10 +504,13 @@ public interface ExecutableCreator {
* @param asyncResultListener The listener where to return partial results
* @return CompressExecutable A {@link CompressExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
CompressExecutable createCompressExecutable(
CompressionMode mode, String src, AsyncResultListener asyncResultListener)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
/**
* Method that creates an executable for uncompress file system objects.
@@ -417,9 +521,12 @@ public interface ExecutableCreator {
* @param asyncResultListener The listener where to return partial results
* @return UncompressExecutable A {@link UncompressExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
+ * @throws NoSuchFileOrDirectory If the file or directory was not found
+ * @throws InsufficientPermissionsException If an operation requires elevated permissions
*/
UncompressExecutable createUncompressExecutable(
String src, String dst, AsyncResultListener asyncResultListener)
- throws CommandNotFoundException;
+ throws CommandNotFoundException,
+ NoSuchFileOrDirectory, InsufficientPermissionsException;
}
diff --git a/src/com/cyanogenmod/filemanager/commands/java/DiskUsageCommand.java b/src/com/cyanogenmod/filemanager/commands/java/DiskUsageCommand.java
index 133de0d4..b0bd1243 100644
--- a/src/com/cyanogenmod/filemanager/commands/java/DiskUsageCommand.java
+++ b/src/com/cyanogenmod/filemanager/commands/java/DiskUsageCommand.java
@@ -78,13 +78,6 @@ public class DiskUsageCommand extends Program implements DiskUsageExecutable {
public void execute()
throws InsufficientPermissionsException, NoSuchFileOrDirectory, ExecutionException {
- //Retrieve the mount points
- MountPointInfoCommand cmd = new MountPointInfoCommand(this.mMountsFile);
- cmd.setBufferSize(getBufferSize());
- cmd.setTrace(isTrace());
- cmd.execute();
- List<MountPoint> mp = cmd.getResult();
-
if (isTrace()) {
Log.v(TAG,
String.format("Getting usage for: %s", //$NON-NLS-1$
@@ -92,19 +85,20 @@ public class DiskUsageCommand extends Program implements DiskUsageExecutable {
}
if (this.mSrc == null) {
+ // Retrieve the mount points
+ MountPointInfoCommand cmd = new MountPointInfoCommand(this.mMountsFile);
+ cmd.setBufferSize(getBufferSize());
+ cmd.setTrace(isTrace());
+ cmd.execute();
+ List<MountPoint> mp = cmd.getResult();
+
+ // Get every disk usage
for (int i = 0; i < mp.size(); i++) {
File root = new File(mp.get(i).getMountPoint());
this.mDisksUsage.add(createDiskUsuage(root));
}
} else {
- // Search the root of file
- for (int i = 0; i < mp.size(); i++) {
- File root = new File(mp.get(i).getMountPoint());
- if (this.mSrc.startsWith(root.getAbsolutePath())) {
- this.mDisksUsage.add(createDiskUsuage(root));
- break;
- }
- }
+ this.mDisksUsage.add(createDiskUsuage(new File(this.mSrc)));
}
if (isTrace()) {
@@ -118,12 +112,12 @@ public class DiskUsageCommand extends Program implements DiskUsageExecutable {
* @param root The root file
* @return DiskUsage The disk usage
*/
- private DiskUsage createDiskUsuage(File root) {
+ private DiskUsage createDiskUsuage(File file) {
DiskUsage du = new DiskUsage(
- root.getAbsolutePath(),
- root.getTotalSpace(),
- root.getTotalSpace() - root.getFreeSpace(),
- root.getFreeSpace());
+ file.getAbsolutePath(),
+ file.getTotalSpace(),
+ file.getTotalSpace() - file.getFreeSpace(),
+ file.getFreeSpace());
if (isTrace()) {
Log.v(TAG, du.toString());
}
diff --git a/src/com/cyanogenmod/filemanager/commands/java/FindCommand.java b/src/com/cyanogenmod/filemanager/commands/java/FindCommand.java
index 17e011e8..793dc616 100644
--- a/src/com/cyanogenmod/filemanager/commands/java/FindCommand.java
+++ b/src/com/cyanogenmod/filemanager/commands/java/FindCommand.java
@@ -16,7 +16,6 @@
package com.cyanogenmod.filemanager.commands.java;
-import android.content.Context;
import android.util.Log;
import com.cyanogenmod.filemanager.commands.AsyncResultListener;
@@ -39,7 +38,6 @@ public class FindCommand extends Program implements FindExecutable {
private static final String TAG = "FindCommand"; //$NON-NLS-1$
- private final Context mCtx;
private final String mDirectory;
private final String[] mQueryRegExp;
private final AsyncResultListener mAsyncResultListener;
@@ -51,15 +49,12 @@ public class FindCommand extends Program implements FindExecutable {
/**
* Constructor of <code>FindCommand</code>.
*
- * @param ctx The current context
* @param directory The absolute directory where start the search
* @param query The terms to be searched
* @param asyncResultListener The partial result listener
*/
- public FindCommand(
- Context ctx, String directory, Query query, AsyncResultListener asyncResultListener) {
+ public FindCommand(String directory, Query query, AsyncResultListener asyncResultListener) {
super();
- this.mCtx = ctx;
this.mDirectory = directory;
this.mQueryRegExp = createRegexp(directory, query);
this.mAsyncResultListener = asyncResultListener;
@@ -145,7 +140,7 @@ public class FindCommand extends Program implements FindExecutable {
for (int j = 0; j < ccc; j++) {
if (files[i].getName().matches(this.mQueryRegExp[j])) {
FileSystemObject fso =
- FileHelper.createFileSystemObject(this.mCtx, files[i]);
+ FileHelper.createFileSystemObject(files[i]);
if (fso != null) {
if (isTrace()) {
Log.v(TAG, String.valueOf(fso));
diff --git a/src/com/cyanogenmod/filemanager/commands/java/JavaExecutableCreator.java b/src/com/cyanogenmod/filemanager/commands/java/JavaExecutableCreator.java
index b43fe7a1..875544ef 100644
--- a/src/com/cyanogenmod/filemanager/commands/java/JavaExecutableCreator.java
+++ b/src/com/cyanogenmod/filemanager/commands/java/JavaExecutableCreator.java
@@ -200,7 +200,7 @@ public class JavaExecutableCreator implements ExecutableCreator {
public FindExecutable createFindExecutable(
String directory, Query query, AsyncResultListener asyncResultListener)
throws CommandNotFoundException {
- return new FindCommand(this.mConsole.getCtx(), directory, query, asyncResultListener);
+ return new FindCommand(directory, query, asyncResultListener);
}
/**
@@ -245,7 +245,7 @@ public class JavaExecutableCreator implements ExecutableCreator {
@Override
public ListExecutable createListExecutable(String src)
throws CommandNotFoundException {
- return new ListCommand(this.mConsole.getCtx(), src, LIST_MODE.DIRECTORY);
+ return new ListCommand(src, LIST_MODE.DIRECTORY);
}
/**
@@ -254,7 +254,7 @@ public class JavaExecutableCreator implements ExecutableCreator {
@Override
public ListExecutable createFileInfoExecutable(String src, boolean followSymlinks)
throws CommandNotFoundException {
- return new ListCommand(this.mConsole.getCtx(), src, LIST_MODE.FILEINFO);
+ return new ListCommand(src, LIST_MODE.FILEINFO);
}
/**
@@ -336,7 +336,7 @@ public class JavaExecutableCreator implements ExecutableCreator {
@Override
public ResolveLinkExecutable createResolveLinkExecutable(String fso)
throws CommandNotFoundException {
- return new ResolveLinkCommand(this.mConsole.getCtx(), fso);
+ return new ResolveLinkCommand(fso);
}
/**
diff --git a/src/com/cyanogenmod/filemanager/commands/java/ListCommand.java b/src/com/cyanogenmod/filemanager/commands/java/ListCommand.java
index 8f1a766e..45e35081 100644
--- a/src/com/cyanogenmod/filemanager/commands/java/ListCommand.java
+++ b/src/com/cyanogenmod/filemanager/commands/java/ListCommand.java
@@ -16,7 +16,6 @@
package com.cyanogenmod.filemanager.commands.java;
-import android.content.Context;
import android.util.Log;
import com.cyanogenmod.filemanager.commands.ListExecutable;
@@ -39,7 +38,6 @@ public class ListCommand extends Program implements ListExecutable {
private static final String TAG = "ListCommand"; //$NON-NLS-1$
- private final Context mCtx;
private final String mSrc;
private final LIST_MODE mMode;
private final List<FileSystemObject> mFiles;
@@ -47,13 +45,11 @@ public class ListCommand extends Program implements ListExecutable {
/**
* Constructor of <code>ListCommand</code>. List mode.
*
- * @param ctx The current context
* @param src The file system object to be listed
* @param mode The mode of listing
*/
- public ListCommand(Context ctx, String src, LIST_MODE mode) {
+ public ListCommand(String src, LIST_MODE mode) {
super();
- this.mCtx = ctx;
this.mSrc = src;
this.mMode = mode;
this.mFiles = new ArrayList<FileSystemObject>();
@@ -100,7 +96,7 @@ public class ListCommand extends Program implements ListExecutable {
File[] files = f.listFiles();
if (files != null) {
for (int i = 0; i < files.length; i++) {
- FileSystemObject fso = FileHelper.createFileSystemObject(this.mCtx, files[i]);
+ FileSystemObject fso = FileHelper.createFileSystemObject(files[i]);
if (fso != null) {
if (isTrace()) {
Log.v(TAG, String.valueOf(fso));
@@ -119,7 +115,7 @@ public class ListCommand extends Program implements ListExecutable {
} else {
// Build the parent information
- FileSystemObject fso = FileHelper.createFileSystemObject(this.mCtx, f);
+ FileSystemObject fso = FileHelper.createFileSystemObject(f);
if (fso != null) {
if (isTrace()) {
Log.v(TAG, String.valueOf(fso));
diff --git a/src/com/cyanogenmod/filemanager/commands/java/ResolveLinkCommand.java b/src/com/cyanogenmod/filemanager/commands/java/ResolveLinkCommand.java
index fe94243e..1cbc1330 100644
--- a/src/com/cyanogenmod/filemanager/commands/java/ResolveLinkCommand.java
+++ b/src/com/cyanogenmod/filemanager/commands/java/ResolveLinkCommand.java
@@ -16,7 +16,6 @@
package com.cyanogenmod.filemanager.commands.java;
-import android.content.Context;
import android.util.Log;
import com.cyanogenmod.filemanager.commands.ListExecutable.LIST_MODE;
@@ -37,19 +36,16 @@ public class ResolveLinkCommand extends Program implements ResolveLinkExecutable
private static final String TAG = "ResolveLinkCommand"; //$NON-NLS-1$
- private final Context mCtx;
private final String mSrc;
private FileSystemObject mFso;
/**
* Constructor of <code>ResolveLinkCommand</code>.
*
- * @param ctx The current context
* @param src The file system object to read
*/
- public ResolveLinkCommand(Context ctx, String src) {
+ public ResolveLinkCommand(String src) {
super();
- this.mCtx = ctx;
this.mSrc = src;
}
@@ -82,7 +78,7 @@ public class ResolveLinkCommand extends Program implements ResolveLinkExecutable
}
try {
String absPath = f.getCanonicalPath();
- ListCommand cmd = new ListCommand(this.mCtx, absPath, LIST_MODE.FILEINFO);
+ ListCommand cmd = new ListCommand(absPath, LIST_MODE.FILEINFO);
cmd.execute();
this.mFso = cmd.getSingleResult();
} catch (Exception e) {
diff --git a/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgram.java b/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgram.java
index 1b1f07d7..64dc0e53 100644
--- a/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgram.java
+++ b/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgram.java
@@ -176,6 +176,7 @@ public abstract class AsyncResultProgram
public final void onRequestParsePartialResult(String partialIn) {
synchronized (this.mSync) {
String data = partialIn;
+ String rest = ""; //$NON-NLS-1$
if (parseOnlyCompleteLines()) {
int pos = partialIn.lastIndexOf(FileHelper.NEWLINE);
if (pos == -1) {
@@ -186,11 +187,12 @@ public abstract class AsyncResultProgram
//Retrieve the data
data = this.mTempBuffer.append(partialIn.substring(0, pos + 1)).toString();
+ rest = partialIn.substring(pos + 1);
}
this.mPartialDataType.add(STDIN);
this.mPartialData.add(data);
- this.mTempBuffer = new StringBuffer();
+ this.mTempBuffer = new StringBuffer(rest);
this.mSync.notify();
}
}
@@ -204,6 +206,7 @@ public abstract class AsyncResultProgram
public final void parsePartialErrResult(String partialErr) {
synchronized (this.mSync) {
String data = partialErr;
+ String rest = ""; //$NON-NLS-1$
if (parseOnlyCompleteLines()) {
int pos = partialErr.lastIndexOf(FileHelper.NEWLINE);
if (pos == -1) {
@@ -214,11 +217,12 @@ public abstract class AsyncResultProgram
//Retrieve the data
data = this.mTempBuffer.append(partialErr.substring(0, pos + 1)).toString();
+ rest = partialErr.substring(pos + 1);
}
this.mPartialDataType.add(STDERR);
this.mPartialData.add(data);
- this.mTempBuffer = new StringBuffer();
+ this.mTempBuffer = new StringBuffer(rest);
this.mSync.notify();
}
}
diff --git a/src/com/cyanogenmod/filemanager/commands/shell/FindCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/FindCommand.java
index 033d5e02..4857a3e3 100644
--- a/src/com/cyanogenmod/filemanager/commands/shell/FindCommand.java
+++ b/src/com/cyanogenmod/filemanager/commands/shell/FindCommand.java
@@ -43,27 +43,16 @@ import java.util.List;
*/
public class FindCommand extends AsyncResultProgram implements FindExecutable {
- //IMP!! This command must returns in the same command a line with the
- //full path of the file, and a list style line of the find file in
- //the next line
- //xe:
- //
- // /mnt/emmc/test79.txt
- // ----rwxr-x system sdcard_rw 0 2012-05-15 12:15 test79.txt
- //
-
private static final String TAG = "FindCommand"; //$NON-NLS-1$
private static final String ID = "find"; //$NON-NLS-1$
- private final String mDirectory;
- private final List<FileSystemObject> mFiles;
- private String mPartial;
+ private final File mDirectory;
/**
* Constructor of <code>FindCommand</code>.
*
- * @param directory The absolute directory where start the search
+ * @param directory The absolute path of the directory where do the search
* @param query The terms to be searched
* @param asyncResultListener The partial result listener
* @throws InvalidCommandDefinitionException If the command has an invalid definition
@@ -71,10 +60,8 @@ public class FindCommand extends AsyncResultProgram implements FindExecutable {
public FindCommand(
String directory, Query query, AsyncResultListener asyncResultListener)
throws InvalidCommandDefinitionException {
- super(ID, asyncResultListener, createArgs(directory, query));
- this.mFiles = new ArrayList<FileSystemObject>();
- this.mPartial = ""; //$NON-NLS-1$
- this.mDirectory = directory;
+ super(ID, asyncResultListener, createArgs(FileHelper.addTrailingSlash(directory), query));
+ this.mDirectory = new File(directory);
}
/**
@@ -82,8 +69,7 @@ public class FindCommand extends AsyncResultProgram implements FindExecutable {
*/
@Override
public void onStartParsePartialResult() {
- this.mFiles.clear();
- this.mPartial = ""; //$NON-NLS-1$
+ //$NON-NLS-1$
}
/**
@@ -91,7 +77,7 @@ public class FindCommand extends AsyncResultProgram implements FindExecutable {
*/
@Override
public void onEndParsePartialResult(boolean cancelled) {
- this.mPartial = ""; //$NON-NLS-1$
+ //$NON-NLS-1$
}
/**
@@ -105,70 +91,34 @@ public class FindCommand extends AsyncResultProgram implements FindExecutable {
BufferedReader br = null;
try {
//Read the partial + previous partial and clean partial
- br = new BufferedReader(new StringReader(this.mPartial + partialIn));
- this.mPartial = ""; //$NON-NLS-1$
+ br = new BufferedReader(new StringReader(partialIn));
//Add all lines to an array
- List<String> lines = new ArrayList<String>();
String line = null;
while ((line = br.readLine()) != null) {
+ //Checks that there is some text in the line. Otherwise ignore it
if (line.trim().length() == 0) {
- continue;
+ break;
}
- lines.add(line);
- }
- //2 lines per file system object translation
- while (lines.size() >= 2) {
+ // Add to the list
try {
- //Data is synchronized?? Have two valid lines?
- if (!lines.get(0).startsWith(File.separator)) {
- //Discard line. The data is no synchronized (some wrong in the output)
- lines.remove(0);
- continue;
- }
- if (lines.get(1).startsWith(File.separator)) {
- //Discard line. The data is no synchronized (some wrong in the output)
- lines.remove(1);
- continue;
- }
+ FileSystemObject fso = ParseHelper.parseStatOutput(line);
- //Extract the parent directory
- String parentDir = new File(lines.get(0)).getParent();
- if (parentDir == null || parentDir.trim().length() == 0) {
- parentDir = FileHelper.ROOT_DIRECTORY;
+ // Search directory is not part of the search
+ if (fso.getFullPath().compareTo(this.mDirectory.getAbsolutePath()) != 0) {
+ partialFiles.add(fso);
}
- //Retrieve the file system object and calculate relevance
- FileSystemObject fso = ParseHelper.toFileSystemObject(parentDir, lines.get(1));
- if (fso.getName() != null && fso.getName().length() > 0) {
- // Don't return the directory of the search. Only files under this
- // directory
- if (this.mDirectory.compareTo(fso.getFullPath()) != 0) {
- String name = new File(lines.get(0)).getName();
- // In some situations, xe when the name has a -> the name is
- // incorrect resolved, but src name should by fine in this case
- fso.setName(name);
- // The symlink is not resolved here
-
- this.mFiles.add(fso);
- partialFiles.add(fso);
- }
+ } catch (Exception e) {
+ // Log the parsing error
+ if (isTrace()) {
+ Log.w(TAG,
+ String.format(
+ "Failed to parse output: %s", //$NON-NLS-1$
+ String.valueOf(line)));
}
-
- } catch (Exception ex) {
- Log.w(TAG, "Partial result fails", ex); //$NON-NLS-1$
}
-
- //Remove the pair of lines
- lines.remove(0);
- lines.remove(0);
- }
-
- //Saves the lines for the next partial read (At this point only one line
- //can exists in the buffer. The rest was processed or discarded)
- if (lines.size() > 0) {
- this.mPartial = lines.get(0).concat(FileHelper.NEWLINE);
}
//If a listener is defined, then send the partial result
diff --git a/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java
index 807e883c..b969018c 100644
--- a/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java
+++ b/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java
@@ -24,14 +24,16 @@ import com.cyanogenmod.filemanager.commands.SIGNAL;
import com.cyanogenmod.filemanager.console.CommandNotFoundException;
import com.cyanogenmod.filemanager.console.ExecutionException;
import com.cyanogenmod.filemanager.console.InsufficientPermissionsException;
+import com.cyanogenmod.filemanager.model.BlockDevice;
+import com.cyanogenmod.filemanager.model.CharacterDevice;
import com.cyanogenmod.filemanager.model.Directory;
-import com.cyanogenmod.filemanager.model.FileSystemObject;
+import com.cyanogenmod.filemanager.model.DomainSocket;
import com.cyanogenmod.filemanager.model.FolderUsage;
+import com.cyanogenmod.filemanager.model.NamedPipe;
import com.cyanogenmod.filemanager.model.Symlink;
import com.cyanogenmod.filemanager.util.FileHelper;
import com.cyanogenmod.filemanager.util.MimeTypeHelper;
import com.cyanogenmod.filemanager.util.MimeTypeHelper.MimeTypeCategory;
-import com.cyanogenmod.filemanager.util.ParseHelper;
import java.io.BufferedReader;
import java.io.StringReader;
@@ -51,7 +53,6 @@ public class FolderUsageCommand extends AsyncResultProgram implements FolderUsag
private final String mDirectory;
private FolderUsage mFolderUsage;
- private String mPartial;
/**
* Constructor of <code>FolderUsageCommand</code>.
@@ -65,7 +66,6 @@ public class FolderUsageCommand extends AsyncResultProgram implements FolderUsag
throws InvalidCommandDefinitionException {
super(ID, asyncResultListener, new String[]{directory});
this.mFolderUsage = new FolderUsage(directory);
- this.mPartial = ""; //$NON-NLS-1$
this.mDirectory = directory;
}
@@ -75,7 +75,6 @@ public class FolderUsageCommand extends AsyncResultProgram implements FolderUsag
@Override
public void onStartParsePartialResult() {
this.mFolderUsage = new FolderUsage(this.mDirectory);
- this.mPartial = ""; //$NON-NLS-1$
}
/**
@@ -83,7 +82,7 @@ public class FolderUsageCommand extends AsyncResultProgram implements FolderUsag
*/
@Override
public void onEndParsePartialResult(boolean cancelled) {
- this.mPartial = ""; //$NON-NLS-1$
+ //$NON-NLS-1$
}
/**
@@ -95,76 +94,100 @@ public class FolderUsageCommand extends AsyncResultProgram implements FolderUsag
// Check the in buffer to extract information
BufferedReader br = null;
try {
- //Read the partial + previous partial and clean partial
- br = new BufferedReader(new StringReader(this.mPartial + partialIn));
- this.mPartial = ""; //$NON-NLS-1$
+ // Parse the line. We expect a ls -l output line
+ // -rw-r--r-- root root 7 2012-12-30 00:49 test.txt
+ //
+ // (1) permissions
+ // (2) owner
+ // (3) group
+ // (4) size
+ // (5) date
+ // (6) name
+
+ //Partial contains full lines
+ br = new BufferedReader(new StringReader(partialIn));
//Add all lines to an array
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = br.readLine()) != null) {
- if (line.trim().length() == 0) {
+ // Discard empty, paths, and folder links
+ if (line.length() == 0 ||
+ line.startsWith(FileHelper.ROOT_DIRECTORY) ||
+ line.startsWith(FileHelper.CURRENT_DIRECTORY) ||
+ line.startsWith(FileHelper.PARENT_DIRECTORY)) {
continue;
}
lines.add(line);
}
- //2 lines per file system object translation
- boolean newData = false;
int c = 0;
- while (lines.size() > 0) {
- try {
+ try {
+ while (lines.size() > 0) {
// Retrieve the info
- String szLine = lines.get(0).trim();
-
- // Parent folder is not necessary here. Only the information relative to
- // type and size
- FileSystemObject fso =
- ParseHelper.toFileSystemObject(
- FileHelper.ROOT_DIRECTORY, szLine, true);
-
- // Only regular files or directories. No compute Symlinks
- if (fso instanceof Symlink) {
-
- // Directory
- } else if (fso instanceof Directory) {
- // Folder
- this.mFolderUsage.addFolder();
- newData = true;
-
- // Regular File, Block device, ...
- } else {
- this.mFolderUsage.addFile();
- // Compute statistics and size
- MimeTypeCategory category =
- MimeTypeHelper.getCategory(null, fso);
- this.mFolderUsage.addFileToCategory(category);
- this.mFolderUsage.addSize(fso.getSize());
- newData = true;
+ String szLine = lines.remove(0).trim();
+ try {
+ // Clean the line (we don't care about names, only need the extension)
+ // so remove spaces is safe here
+ while (szLine.indexOf(" ") != -1) { //$NON-NLS-1$
+ szLine = szLine.replaceAll(" ", " "); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ char type = szLine.charAt(0);
+ if (type == Symlink.UNIX_ID ||
+ type == BlockDevice.UNIX_ID ||
+ type == CharacterDevice.UNIX_ID ||
+ type == DomainSocket.UNIX_ID ||
+ type == NamedPipe.UNIX_ID) {
+ // File + Category
+ this.mFolderUsage.addFile();
+ if (type == Symlink.UNIX_ID) {
+ this.mFolderUsage.addFileToCategory(MimeTypeCategory.NONE);
+ } else {
+ this.mFolderUsage.addFileToCategory(MimeTypeCategory.SYSTEM);
+ }
+
+ } else if (type == Directory.UNIX_ID) {
+ // Folder
+ this.mFolderUsage.addFolder();
+
+ } else {
+ // File + Category + Size
+ try {
+ // we need a valid line
+ String[] fields = szLine.split(" "); //$NON-NLS-1$
+ if (fields.length < 7) {
+ continue;
+ }
+
+ long size = Long.parseLong(fields[3]);
+ String name = fields[fields.length-1];// We only need the extension
+ String ext = FileHelper.getExtension(name);
+ MimeTypeCategory category =
+ MimeTypeHelper.getCategoryFromExt(null, ext);
+ this.mFolderUsage.addFile();
+ this.mFolderUsage.addFileToCategory(category);
+ this.mFolderUsage.addSize(size);
+ } catch (Exception e) {/**NON BLOCK**/}
+ }
+ c++;
+
+ } catch (Exception e) {
+ // Ignore.
}
// Partial notification
if (c % 5 == 0) {
//If a listener is defined, then send the partial result
- if (getAsyncResultListener() != null && newData) {
+ if (getAsyncResultListener() != null) {
getAsyncResultListener().onPartialResult(this.mFolderUsage);
}
}
-
- } catch (Exception ex) { /**NON BLOCK **/ }
-
- //Remove the the line
- lines.remove(0);
- }
-
- //Saves the lines for the next partial read (At this point only one line
- //can exists in the buffer. The rest was processed or discarded)
- if (lines.size() > 0) {
- this.mPartial = lines.get(0).concat(FileHelper.NEWLINE);
- }
+ }
+ } catch (Exception ex) { /**NON BLOCK **/ }
//If a listener is defined, then send the partial result
- if (getAsyncResultListener() != null && newData) {
+ if (getAsyncResultListener() != null) {
getAsyncResultListener().onPartialResult(this.mFolderUsage);
}
diff --git a/src/com/cyanogenmod/filemanager/commands/shell/ListCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/ListCommand.java
index bb05da82..c6228d18 100644
--- a/src/com/cyanogenmod/filemanager/commands/shell/ListCommand.java
+++ b/src/com/cyanogenmod/filemanager/commands/shell/ListCommand.java
@@ -16,19 +16,15 @@
package com.cyanogenmod.filemanager.commands.shell;
-import com.cyanogenmod.filemanager.FileManagerApplication;
+import android.util.Log;
+
import com.cyanogenmod.filemanager.commands.ListExecutable;
import com.cyanogenmod.filemanager.console.CommandNotFoundException;
-import com.cyanogenmod.filemanager.console.ConsoleAllocException;
import com.cyanogenmod.filemanager.console.ExecutionException;
import com.cyanogenmod.filemanager.console.InsufficientPermissionsException;
-import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
-import com.cyanogenmod.filemanager.console.OperationTimeoutException;
import com.cyanogenmod.filemanager.console.shell.ShellConsole;
import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.model.ParentDirectory;
-import com.cyanogenmod.filemanager.model.Symlink;
-import com.cyanogenmod.filemanager.util.CommandHelper;
import com.cyanogenmod.filemanager.util.FileHelper;
import com.cyanogenmod.filemanager.util.ParseHelper;
@@ -45,17 +41,15 @@ import java.util.List;
/**
* A class for list information about files and directories.
*
- * {@link "http://unixhelp.ed.ac.uk/CGI/man-cgi?ls"}
+ * {@link "http://unixhelp.ed.ac.uk/CGI/man-cgi?stat"}
*/
public class ListCommand extends SyncResultProgram implements ListExecutable {
- private static final String ID_LS_DIRECTORY = "ls"; //$NON-NLS-1$
- private static final String ID_LS_INFO = "fileinfo"; //$NON-NLS-1$
+ private static final String TAG = "ListCommand"; //$NON-NLS-1$
- private static final String SYMLINK_REF = ">SIMLINKS>"; //$NON-NLS-1$
- private static final String SYMLINK_DATA_REF = ">SIMLINKS_DATA>"; //$NON-NLS-1$
+ private static final String ID_LS = "ls"; //$NON-NLS-1$
+ private static final String ID_FILEINFO = "fileinfo"; //$NON-NLS-1$
- private final String mSrc;
private final LIST_MODE mMode;
private final List<FileSystemObject> mFiles;
private String mParentDir;
@@ -67,37 +61,22 @@ public class ListCommand extends SyncResultProgram implements ListExecutable {
* @param console The console in which retrieve the parent directory information.
* <code>null</code> to attach to the default console
* @throws InvalidCommandDefinitionException If the command has an invalid definition
- * @throws FileNotFoundException If the initial directory not exists
- * @throws NoSuchFileOrDirectory If the file or directory was not found
- * @throws IOException If initial directory couldn't be checked
- * @throws ConsoleAllocException If the console can't be allocated
- * @throws InsufficientPermissionsException If an operation requires elevated permissions
- * @throws CommandNotFoundException If the command was not found
- * @throws OperationTimeoutException If the operation exceeded the maximum time of wait
- * @throws ExecutionException If the operation returns a invalid exit code
*/
public ListCommand(String src, ShellConsole console)
- throws InvalidCommandDefinitionException, FileNotFoundException,
- NoSuchFileOrDirectory, IOException, ConsoleAllocException,
- InsufficientPermissionsException, CommandNotFoundException,
- OperationTimeoutException, ExecutionException {
- //If the mode is listing directory, for avoid problems with symlink,
- //always append a / to the end of the path (if not exists)
- super(ID_LS_DIRECTORY, new String[]{ FileHelper.addTrailingSlash(src) });
+ throws InvalidCommandDefinitionException {
+ // Always add backslash for list the files of the directory, instead of
+ // the directory.
+ super(ID_LS, new String[]{ FileHelper.addTrailingSlash(src) });
//Initialize files to something distinct of null
this.mFiles = new ArrayList<FileSystemObject>();
this.mMode = LIST_MODE.DIRECTORY;
- this.mSrc = src;
//Retrieve parent directory information
if (src.compareTo(FileHelper.ROOT_DIRECTORY) == 0) {
this.mParentDir = null;
} else {
- this.mParentDir =
- CommandHelper.getAbsolutePath(
- FileManagerApplication.
- getInstance().getApplicationContext(), src, console);
+ this.mParentDir = new File(src).getAbsolutePath();
}
}
@@ -110,22 +89,13 @@ public class ListCommand extends SyncResultProgram implements ListExecutable {
* <code>null</code> to attach to the default console
* @throws InvalidCommandDefinitionException If the command has an invalid definition
* @throws FileNotFoundException If the initial directory not exists
- * @throws NoSuchFileOrDirectory If the file or directory was not found
* @throws IOException If initial directory couldn't be checked
- * @throws ConsoleAllocException If the console can't be allocated
- * @throws InsufficientPermissionsException If an operation requires elevated permissions
- * @throws CommandNotFoundException If the command was not found
- * @throws OperationTimeoutException If the operation exceeded the maximum time of wait
- * @throws ExecutionException If the operation returns a invalid exit code
*/
public ListCommand(String src, boolean followSymlinks, ShellConsole console)
- throws InvalidCommandDefinitionException, FileNotFoundException,
- NoSuchFileOrDirectory, IOException, ConsoleAllocException,
- InsufficientPermissionsException, CommandNotFoundException,
- OperationTimeoutException, ExecutionException {
- //If the mode is listing directory, for avoid problems with symlink,
- //always append a / to the end of the path (if not exists)
- super(ID_LS_INFO,
+ throws InvalidCommandDefinitionException, FileNotFoundException, IOException {
+ // Always remove backslash for avoid listing the files of the directory, instead of
+ // the directory.
+ super(ID_FILEINFO,
new String[]{
FileHelper.removeTrailingSlash(
followSymlinks ?
@@ -135,31 +105,16 @@ public class ListCommand extends SyncResultProgram implements ListExecutable {
//Initialize files to something distinct of null
this.mFiles = new ArrayList<FileSystemObject>();
this.mMode = LIST_MODE.FILEINFO;
- this.mSrc = src;
//Get the absolute path
- try {
- if (followSymlinks) {
- this.mParentDir =
- FileHelper.removeTrailingSlash(
- new File(src).getCanonicalFile().getParent());
- } else {
- this.mParentDir =
- FileHelper.removeTrailingSlash(
- new File(src).getAbsoluteFile().getParent());
- }
-
- } catch (Exception e) {
- // Try to resolve from a console
- String abspath =
- CommandHelper.getAbsolutePath(
- FileManagerApplication.getInstance().
- getApplicationContext(), src, console);
- //Resolve the parent directory
+ if (followSymlinks) {
this.mParentDir =
- CommandHelper.getParentDir(
- FileManagerApplication.getInstance().getApplicationContext(),
- abspath, console);
+ FileHelper.removeTrailingSlash(
+ new File(src).getCanonicalFile().getParent());
+ } else {
+ this.mParentDir =
+ FileHelper.removeTrailingSlash(
+ new File(src).getAbsoluteFile().getParent());
}
}
@@ -171,150 +126,29 @@ public class ListCommand extends SyncResultProgram implements ListExecutable {
//Release the array
this.mFiles.clear();
- // Check the in buffer to extract information
+ // Read every line and parse it
BufferedReader br = null;
- int line = 0;
try {
br = new BufferedReader(new StringReader(in));
- String szLine = null;
- boolean symlinks = false;
- int symlinksCount = 0;
- while ((szLine = br.readLine()) != null) {
+ String line = null;
+ while ((line = br.readLine()) != null) {
//Checks that there is some text in the line. Otherwise ignore it
- if (szLine.trim().length() == 0) {
+ if (line.trim().length() == 0) {
break;
}
- //For a fast recovery, command return non symlink first and
- //symlinks files, the resolution and the his info
- //Is now symlinks?
- if (szLine.startsWith(SYMLINK_REF)) {
- //Ignore the control line
- szLine = br.readLine();
- line++;
- symlinks = true;
- }
-
- //Parse the line into a FileSystemObject reference
- if (!symlinks) {
- try {
- FileSystemObject fso =
- ParseHelper.toFileSystemObject(this.mParentDir, szLine);
- if (this.mMode.compareTo(LIST_MODE.FILEINFO) == 0 &&
- fso instanceof Symlink) {
- // In some situations, xe when the name has a -> the name is
- // incorrect resolved, but src name should by fine in this case
- fso.setName(new File(this.mSrc).getName());
- // The symlink is not resolved here
- }
- this.mFiles.add(fso);
- } catch (ParseException pEx) {
- throw new ParseException(pEx.getMessage(), line);
- }
- } else {
- //Is ending symlink reference
- if (szLine.startsWith(SYMLINK_DATA_REF)) {
- if (symlinksCount == 0) {
- //No more data
- break;
- }
- //Ignore the control line
- szLine = br.readLine();
- line++;
-
- //The next information is known: symlinksCount * 3
- String[] name = new String[symlinksCount];
- String[] absPath = new String[symlinksCount];
- String[] refPath = new String[symlinksCount];
- for (int i = 0; i < symlinksCount; i++) {
- if (szLine == null || szLine.trim().length() == 0) {
- name[i] = null;
- szLine = br.readLine();
- line++;
- continue;
- }
- name[i] = szLine;
- szLine = br.readLine();
- line++;
- }
- for (int i = 0; i < symlinksCount; i++) {
- if (szLine == null || szLine.trim().length() == 0) {
- absPath[i] = null;
- szLine = br.readLine();
- line++;
- continue;
- }
- absPath[i] = szLine;
- szLine = br.readLine();
- line++;
- }
- for (int i = 0; i < symlinksCount; i++) {
- if (szLine == null || szLine.trim().length() == 0) {
- refPath[i] = null;
- szLine = br.readLine();
- line++;
- continue;
- }
- refPath[i] = szLine;
- szLine = br.readLine();
- line++;
- }
-
- //Fill the parent if is null
- for (int i = 0; i < symlinksCount; i++) {
- Symlink symLink =
- ((Symlink)this.mFiles.get(
- this.mFiles.size() - symlinksCount + i));
- if (symLink.getParent() == null) {
- symLink.setParent(FileHelper.ROOT_DIRECTORY);
- }
- }
-
- // Symlink can cause incoherences in the name because "->" string
- // Now, we have the real name of the symlink
- for (int i = 0; i < symlinksCount; i++) {
- if (name[i] != null) {
- Symlink symLink =
- ((Symlink)this.mFiles.get(
- this.mFiles.size() - symlinksCount + i));
- symLink.setName(name[i]);
- }
- }
-
- //Fill the data
- for (int i = 0; i < symlinksCount; i++) {
- try {
- if (absPath[i] != null && absPath[i].length() > 0) {
- Symlink symLink =
- ((Symlink)this.mFiles.get(
- this.mFiles.size() - symlinksCount + i));
- String parentLink = new File(absPath[i]).getParent();
- if (parentLink == null) {
- parentLink = FileHelper.ROOT_DIRECTORY;
- }
- String info = refPath[i];
- FileSystemObject fsoRef =
- ParseHelper.toFileSystemObject(parentLink, info);
- symLink.setLinkRef(fsoRef);
- }
- } catch (Throwable ex) {
- //If parsing the file failed, ignore it and threat as a regular
- //file (the destination file not exists or can't be resolved)
- }
- }
- break;
- }
-
- //Add the symlink
- try {
- this.mFiles.add(ParseHelper.toFileSystemObject(this.mParentDir, szLine));
- symlinksCount++;
- } catch (ParseException pEx) {
- throw new ParseException(pEx.getMessage(), line);
+ // Parse and add to result files
+ try {
+ this.mFiles.add(ParseHelper.parseStatOutput(line));
+ } catch (Exception e) {
+ // Log the parsing error
+ if (isTrace()) {
+ Log.w(TAG,
+ String.format(
+ "Failed to parse output: %s", //$NON-NLS-1$
+ String.valueOf(line)));
}
}
-
- line++;
}
// Add the parent directory
@@ -325,13 +159,10 @@ public class ListCommand extends SyncResultProgram implements ListExecutable {
}
} catch (IOException ioEx) {
- throw new ParseException(ioEx.getMessage(), line);
-
- } catch (ParseException pEx) {
- throw pEx;
+ throw new ParseException(ioEx.getMessage(), 0);
} catch (Exception ex) {
- throw new ParseException(ex.getMessage(), line);
+ throw new ParseException(ex.getMessage(), 0);
} finally {
try {
diff --git a/src/com/cyanogenmod/filemanager/commands/shell/ReadCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/ReadCommand.java
index d6617f48..cd2232ba 100644
--- a/src/com/cyanogenmod/filemanager/commands/shell/ReadCommand.java
+++ b/src/com/cyanogenmod/filemanager/commands/shell/ReadCommand.java
@@ -96,6 +96,14 @@ public class ReadCommand extends AsyncResultProgram implements ReadExecutable {
* {@inheritDoc}
*/
@Override
+ public boolean parseOnlyCompleteLines() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void checkExitCode(int exitCode)
throws InsufficientPermissionsException, CommandNotFoundException, ExecutionException {
// We have not privileges to read the file
diff --git a/src/com/cyanogenmod/filemanager/commands/shell/ResolveLinkCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/ResolveLinkCommand.java
index f3d764f1..575144a1 100644
--- a/src/com/cyanogenmod/filemanager/commands/shell/ResolveLinkCommand.java
+++ b/src/com/cyanogenmod/filemanager/commands/shell/ResolveLinkCommand.java
@@ -63,9 +63,10 @@ public class ResolveLinkCommand extends SyncResultProgram implements ResolveLink
BufferedReader br = null;
try {
br = new BufferedReader(new StringReader(in));
- String szParentDir = br.readLine();
- String szFileInfo = br.readLine();
- this.mFso = ParseHelper.toFileSystemObject(szParentDir, szFileInfo);
+
+ // Extract and parse the stat output
+ String line = br.readLine();
+ this.mFso = ParseHelper.parseStatOutput(line);
} catch (Exception ex) {
throw new ParseException(ex.getMessage(), 0);
@@ -95,6 +96,6 @@ public class ResolveLinkCommand extends SyncResultProgram implements ResolveLink
@Override
public void checkExitCode(int exitCode)
throws InsufficientPermissionsException, CommandNotFoundException, ExecutionException {
- //Safely ignore
+ /**NON BLOCK**/
}
}
diff --git a/src/com/cyanogenmod/filemanager/commands/shell/ShellExecutableCreator.java b/src/com/cyanogenmod/filemanager/commands/shell/ShellExecutableCreator.java
index 4eabd8f3..adc2ea68 100644
--- a/src/com/cyanogenmod/filemanager/commands/shell/ShellExecutableCreator.java
+++ b/src/com/cyanogenmod/filemanager/commands/shell/ShellExecutableCreator.java
@@ -311,8 +311,7 @@ public class ShellExecutableCreator implements ExecutableCreator {
* {@inheritDoc}
*/
@Override
- public ListExecutable createListExecutable(String src)
- throws CommandNotFoundException {
+ public ListExecutable createListExecutable(String src) throws CommandNotFoundException {
try {
return new ListCommand(src, this.mConsole);
} catch (Throwable throwEx) {
diff --git a/src/com/cyanogenmod/filemanager/commands/shell/SyncResultProgram.java b/src/com/cyanogenmod/filemanager/commands/shell/SyncResultProgram.java
index ef363b9c..2d73e58c 100644
--- a/src/com/cyanogenmod/filemanager/commands/shell/SyncResultProgram.java
+++ b/src/com/cyanogenmod/filemanager/commands/shell/SyncResultProgram.java
@@ -16,6 +16,7 @@
package com.cyanogenmod.filemanager.commands.shell;
+
/**
* An abstract class that allow the consumption of the data when it's totally recovery.
*/
diff --git a/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java b/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java
index fb3b5075..e7de2fbf 100644
--- a/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java
+++ b/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java
@@ -72,7 +72,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
// A timeout of 5 seconds should be enough for no-debugging environments
private static final long DEFAULT_TIMEOUT =
- FileManagerApplication.isDebuggable() ? 20000L : 5000L;
+ FileManagerApplication.isDebuggable() ? 20000L : 3000L;
private static final int DEFAULT_BUFFER = 512;
@@ -312,7 +312,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
this.mIdentity.setGroups(groupsCmd.getResult());
}
} catch (Exception ex) {
- Log.w(TAG, "Groups command failed. Ignored.", ex);
+ Log.w(TAG, "Groups command failed. Ignored.", ex); //$NON-NLS-1$
}
} catch (Exception ex) {
@@ -504,7 +504,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
(program instanceof AsyncResultProgram &&
((AsyncResultProgram)program).isExpectEnd()));
- this.mStartControlPattern = startId1 + "\\d{1,3}" + startId2 + "\\n"; //$NON-NLS-1$ //$NON-NLS-2$
+ this.mStartControlPattern = startId1 + "\\d{1,3}" + startId2; //$NON-NLS-1$
this.mEndControlPattern = endId1 + "\\d{1,3}" + endId2; //$NON-NLS-1$
String startCmd =
Command.getStartCodeCommandInfo(
@@ -529,7 +529,10 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
.append(endCmd);
}
sb.append(FileHelper.NEWLINE);
- this.mOut.write(sb.toString().getBytes());
+ synchronized (this.mSync) {
+ this.mFinished = false;
+ this.mOut.write(sb.toString().getBytes());
+ }
} catch (InvalidCommandDefinitionException icdEx) {
throw new CommandNotFoundException(
"ExitCodeCommandInfo not found", icdEx); //$NON-NLS-1$
@@ -537,12 +540,14 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
//Now, wait for buffers to be filled
synchronized (this.mSync) {
- if (program instanceof AsyncResultProgram) {
- this.mSync.wait();
- } else {
- this.mSync.wait(DEFAULT_TIMEOUT);
- if (!this.mFinished) {
- throw new OperationTimeoutException(DEFAULT_TIMEOUT, cmd);
+ if (!this.mFinished) {
+ if (program instanceof AsyncResultProgram) {
+ this.mSync.wait();
+ } else {
+ this.mSync.wait(DEFAULT_TIMEOUT);
+ if (!this.mFinished) {
+ throw new OperationTimeoutException(DEFAULT_TIMEOUT, cmd);
+ }
}
}
}
@@ -629,10 +634,11 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
*/
private Thread createStdInThread(final InputStream in) {
Thread t = new Thread(new Runnable() {
+ @SuppressWarnings("synthetic-access")
@Override
public void run() {
int read = 0;
-
+ StringBuffer sb = null;
try {
while (ShellConsole.this.mActive) {
//Read only one byte with active wait
@@ -645,14 +651,17 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
boolean async =
ShellConsole.this.mActiveCommand != null &&
ShellConsole.this.mActiveCommand instanceof AsyncResultProgram;
+ if (!async || sb == null) {
+ sb = new StringBuffer();
+ }
- StringBuffer sb = new StringBuffer();
if (!ShellConsole.this.mCancelled) {
ShellConsole.this.mSbIn.append((char)r);
if (!ShellConsole.this.mStarted) {
ShellConsole.this.mStarted =
isCommandStarted(ShellConsole.this.mSbIn);
if (ShellConsole.this.mStarted) {
+
sb = new StringBuffer(ShellConsole.this.mSbIn.toString());
if (async) {
synchronized (ShellConsole.this.mPartialSync) {
@@ -668,21 +677,44 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
sb.append((char)r);
}
+ //Check if the command has finished (and extract the control)
+ boolean finished = isCommandFinished(ShellConsole.this.mSbIn, sb);
+
//Notify asynchronous partial data
if (ShellConsole.this.mStarted && async) {
AsyncResultProgram program =
((AsyncResultProgram)ShellConsole.this.mActiveCommand);
String partial = sb.toString();
- program.onRequestParsePartialResult(partial);
- ShellConsole.this.toStdIn(partial);
+ int cc = ShellConsole.this.mEndControlPattern.length();
+ if (partial.length() >= cc) {
+ program.onRequestParsePartialResult(partial);
+ ShellConsole.this.toStdIn(partial);
- // Reset the temp buffer
- sb = new StringBuffer();
+ // Reset the temp buffer
+ sb = new StringBuffer();
+ }
}
- }
- if (!async) {
- ShellConsole.this.toStdIn(sb.toString());
+ if (finished) {
+ if (!async) {
+ ShellConsole.this.toStdIn(String.valueOf((char)r));
+ } else {
+ AsyncResultProgram program =
+ ((AsyncResultProgram)ShellConsole.this.mActiveCommand);
+ String partial = sb.toString();
+ if (program != null) {
+ program.onRequestParsePartialResult(partial);
+ }
+ ShellConsole.this.toStdIn(partial);
+ }
+
+ //Notify the end
+ notifyProcessFinished();
+ break;
+ }
+ if (!async && !finished) {
+ ShellConsole.this.toStdIn(String.valueOf((char)r));
+ }
}
//Has more data? Read with available as more as exists
@@ -690,8 +722,8 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
int count = 0;
while (in.available() > 0 && count < 10) {
count++;
- int available = Math.min(in.available(),
- ShellConsole.this.mBufferSize);
+ int available =
+ Math.min(in.available(), ShellConsole.this.mBufferSize);
byte[] data = new byte[available];
read = in.read(data);
@@ -735,18 +767,29 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
AsyncResultProgram program =
((AsyncResultProgram)ShellConsole.this.mActiveCommand);
String partial = sb.toString();
- if (program != null) {
- program.onRequestParsePartialResult(partial);
- }
- ShellConsole.this.toStdIn(partial);
+ int cc = ShellConsole.this.mEndControlPattern.length();
+ if (partial.length() >= cc) {
+ if (program != null) {
+ program.onRequestParsePartialResult(partial);
+ }
+ ShellConsole.this.toStdIn(partial);
- // Reset the temp buffer
- sb = new StringBuffer();
+ // Reset the temp buffer
+ sb = new StringBuffer();
+ }
}
if (finished) {
if (!async) {
ShellConsole.this.toStdIn(s);
+ } else {
+ AsyncResultProgram program =
+ ((AsyncResultProgram)ShellConsole.this.mActiveCommand);
+ String partial = sb.toString();
+ if (program != null) {
+ program.onRequestParsePartialResult(partial);
+ }
+ ShellConsole.this.toStdIn(partial);
}
//Notify the end
@@ -759,10 +802,8 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis
//Wait for buffer to be filled
try {
- Thread.sleep(50L);
- } catch (Throwable ex) {
- /**NON BLOCK**/
- }
+ Thread.sleep(1L);
+ } catch (Throwable ex) {/**NON BLOCK**/}
}
//Asynchronous programs can cause a lot of output, control buffers
diff --git a/src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java b/src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java
index 216b787b..0de97198 100644
--- a/src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java
+++ b/src/com/cyanogenmod/filemanager/listeners/OnRequestRefreshListener.java
@@ -25,15 +25,17 @@ public interface OnRequestRefreshListener {
* Invoked when a new refresh is needed.
*
* @param o The object that should be refreshed
+ * @param clearSelection If the refresh should clear the selection
*/
- void onRequestRefresh(Object o);
+ void onRequestRefresh(Object o, boolean clearSelection);
/**
* Invoked when the object was removed.
*
* @param o The object that was removed
+ * @param clearSelection If the refresh should clear the selection
*/
- void onRequestRemove(Object o);
+ void onRequestRemove(Object o, boolean clearSelection);
/**
* Invoked when the object need to navigate to.
diff --git a/src/com/cyanogenmod/filemanager/model/BlockDevice.java b/src/com/cyanogenmod/filemanager/model/BlockDevice.java
index 5fa56531..31873b36 100644
--- a/src/com/cyanogenmod/filemanager/model/BlockDevice.java
+++ b/src/com/cyanogenmod/filemanager/model/BlockDevice.java
@@ -25,7 +25,7 @@ import java.util.Date;
*/
public class BlockDevice extends SystemFile {
- private static final long serialVersionUID = -4090113368100371854L;
+ private static final long serialVersionUID = 5938248951823805680L;
/**
* The unix identifier of the object.
@@ -41,11 +41,15 @@ public class BlockDevice extends SystemFile {
* @param user The user proprietary of the object
* @param group The group proprietary of the object
* @param permissions The permissions of the object
+ * @param lastAccessedTime The last time that the object was accessed
* @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
*/
- public BlockDevice(String name, String parent, User user, Group group, Permissions permissions,
- Date lastModifiedTime) {
- super(name, parent, user, group, permissions, lastModifiedTime, 0L);
+ public BlockDevice(
+ String name, String parent, User user, Group group, Permissions permissions,
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime) {
+ super(name, parent, user, group, permissions, 0L,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
}
/**
diff --git a/src/com/cyanogenmod/filemanager/model/CharacterDevice.java b/src/com/cyanogenmod/filemanager/model/CharacterDevice.java
index 77c35c7e..489e05ad 100644
--- a/src/com/cyanogenmod/filemanager/model/CharacterDevice.java
+++ b/src/com/cyanogenmod/filemanager/model/CharacterDevice.java
@@ -25,7 +25,7 @@ import java.util.Date;
*/
public class CharacterDevice extends SystemFile {
- private static final long serialVersionUID = -1226283292403290607L;
+ private static final long serialVersionUID = -3585051204874199619L;
/**
* The unix identifier of the object.
@@ -41,12 +41,15 @@ public class CharacterDevice extends SystemFile {
* @param user The user proprietary of the object
* @param group The group proprietary of the object
* @param permissions The permissions of the object
+ * @param lastAccessedTime The last time that the object was accessed
* @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
*/
public CharacterDevice(
- String name, String parent, User user, Group group,
- Permissions permissions, Date lastModifiedTime) {
- super(name, parent, user, group, permissions, lastModifiedTime, 0L);
+ String name, String parent, User user, Group group, Permissions permissions,
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime) {
+ super(name, parent, user, group, permissions, 0L,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
}
/**
diff --git a/src/com/cyanogenmod/filemanager/model/Directory.java b/src/com/cyanogenmod/filemanager/model/Directory.java
index ff1bc8d9..77b12081 100644
--- a/src/com/cyanogenmod/filemanager/model/Directory.java
+++ b/src/com/cyanogenmod/filemanager/model/Directory.java
@@ -25,7 +25,7 @@ import java.util.Date;
*/
public class Directory extends FileSystemObject {
- private static final long serialVersionUID = 7961695438008458932L;
+ private static final long serialVersionUID = -3975569940766905884L;
//Resource identifier for default icon
private static final int RESOURCE_FOLDER_DEFAULT = R.drawable.ic_fso_folder;
@@ -44,11 +44,14 @@ public class Directory extends FileSystemObject {
* @param user The user proprietary of the object
* @param group The group proprietary of the object
* @param permissions The permissions of the object
+ * @param lastAccessedTime The last time that the object was accessed
* @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
*/
public Directory(String name, String parent, User user, Group group, Permissions permissions,
- Date lastModifiedTime) {
- super(name, parent, user, group, permissions, lastModifiedTime, 0L);
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime) {
+ super(name, parent, user, group, permissions, 0L,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
setResourceIconId(RESOURCE_FOLDER_DEFAULT);
}
diff --git a/src/com/cyanogenmod/filemanager/model/DomainSocket.java b/src/com/cyanogenmod/filemanager/model/DomainSocket.java
index ca0f54d6..c7d9af1f 100644
--- a/src/com/cyanogenmod/filemanager/model/DomainSocket.java
+++ b/src/com/cyanogenmod/filemanager/model/DomainSocket.java
@@ -25,7 +25,7 @@ import java.util.Date;
*/
public class DomainSocket extends SystemFile {
- private static final long serialVersionUID = 2579603247387819438L;
+ private static final long serialVersionUID = 7821422013567568593L;
/**
* The unix identifier of the object.
@@ -41,11 +41,15 @@ public class DomainSocket extends SystemFile {
* @param user The user proprietary of the object
* @param group The group proprietary of the object
* @param permissions The permissions of the object
+ * @param lastAccessedTime The last time that the object was accessed
* @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
*/
- public DomainSocket(String name, String parent, User user, Group group, Permissions permissions,
- Date lastModifiedTime) {
- super(name, parent, user, group, permissions, lastModifiedTime, 0L);
+ public DomainSocket(
+ String name, String parent, User user, Group group, Permissions permissions,
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime) {
+ super(name, parent, user, group, permissions, 0L,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
}
/**
diff --git a/src/com/cyanogenmod/filemanager/model/FileSystemObject.java b/src/com/cyanogenmod/filemanager/model/FileSystemObject.java
index 245ebce5..75745c4b 100644
--- a/src/com/cyanogenmod/filemanager/model/FileSystemObject.java
+++ b/src/com/cyanogenmod/filemanager/model/FileSystemObject.java
@@ -33,7 +33,7 @@ import java.util.Date;
*/
public abstract class FileSystemObject implements Serializable, Comparable<FileSystemObject> {
- private static final long serialVersionUID = -8527561430880927320L;
+ private static final long serialVersionUID = 5877049750925761305L;
//Resource identifier for default icon
private static final int RESOURCE_ICON_DEFAULT = R.drawable.ic_fso_default;
@@ -44,8 +44,11 @@ public abstract class FileSystemObject implements Serializable, Comparable<FileS
private User mUser;
private Group mGroup;
private Permissions mPermissions;
- private Date mLastModifiedTime;
private long mSize;
+ private Date mLastAccessedTime;
+ private Date mLastModifiedTime;
+ private Date mLastChangedTime;
+
/**
* Constructor of <code>FileSystemObject</code>.
@@ -55,19 +58,24 @@ public abstract class FileSystemObject implements Serializable, Comparable<FileS
* @param user The user proprietary of the object
* @param group The group proprietary of the object
* @param permissions The permissions of the object
- * @param lastModifiedTime The last time that the object was modified
* @param size The size in bytes of the object
+ * @param lastAccessedTime The last time that the object was accessed
+ * @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
*/
public FileSystemObject(String name, String parent, User user, Group group,
- Permissions permissions, Date lastModifiedTime, long size) {
+ Permissions permissions, long size,
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime) {
super();
this.mName = name;
this.mParent = parent;
this.mUser = user;
this.mGroup = group;
this.mPermissions = permissions;
- this.mLastModifiedTime = lastModifiedTime;
this.mSize = size;
+ this.mLastAccessedTime = lastAccessedTime;
+ this.mLastModifiedTime = lastModifiedTime;
+ this.mLastChangedTime = lastChangedTime;
this.mResourceIconId = RESOURCE_ICON_DEFAULT;
}
@@ -169,6 +177,42 @@ public abstract class FileSystemObject implements Serializable, Comparable<FileS
}
/**
+ * Method that returns the size in bytes of the object.
+ *
+ * @return long The size in bytes of the object
+ */
+ public long getSize() {
+ return this.mSize;
+ }
+
+ /**
+ * Method that sets the size in bytes of the object.
+ *
+ * @param size The size in bytes of the object
+ */
+ public void setSize(long size) {
+ this.mSize = size;
+ }
+
+ /**
+ * Method that returns the last time that the object was accessed.
+ *
+ * @return Date The last time that the object was accessed
+ */
+ public Date getLastAccessedTime() {
+ return this.mLastAccessedTime;
+ }
+
+ /**
+ * Method that sets the last time that the object was accessed.
+ *
+ * @param lastAccessedTime The last time that the object was accessed
+ */
+ public void setLastAccessedTime(Date lastAccessedTime) {
+ this.mLastAccessedTime = lastAccessedTime;
+ }
+
+ /**
* Method that returns the last time that the object was modified.
*
* @return Date The last time that the object was modified
@@ -187,21 +231,21 @@ public abstract class FileSystemObject implements Serializable, Comparable<FileS
}
/**
- * Method that returns the size in bytes of the object.
+ * Method that returns the last time that the object was changed.
*
- * @return long The size in bytes of the object
+ * @return Date The last time that the object was changed
*/
- public long getSize() {
- return this.mSize;
+ public Date getLastChangedTime() {
+ return this.mLastChangedTime;
}
/**
- * Method that sets the size in bytes of the object.
+ * Method that sets the last time that the object was changed.
*
- * @param size The size in bytes of the object
+ * @param lastChangedTime The last time that the object was changed
*/
- public void setSize(long size) {
- this.mSize = size;
+ public void setLastChangedTime(Date lastChangedTime) {
+ this.mLastChangedTime = lastChangedTime;
}
/**
@@ -262,89 +306,38 @@ public abstract class FileSystemObject implements Serializable, Comparable<FileS
return o1.compareTo(o2);
}
- /**
- * {@inheritDoc}
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((this.mGroup == null) ? 0 : this.mGroup.hashCode());
- result = prime * result + ((this.mLastModifiedTime == null)
- ? 0
- : this.mLastModifiedTime.hashCode());
result = prime * result + ((this.mName == null) ? 0 : this.mName.hashCode());
result = prime * result + ((this.mParent == null) ? 0 : this.mParent.hashCode());
- result = prime * result + ((this.mPermissions == null) ? 0 : this.mPermissions.hashCode());
- result = prime * result + this.mResourceIconId;
- result = prime * result + (int) (this.mSize ^ (this.mSize >>> 32));
- result = prime * result + ((this.mUser == null) ? 0 : this.mUser.hashCode());
return result;
}
- /**
- * {@inheritDoc}
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
- if (this == obj) {
+ if (this == obj)
return true;
- }
- if (obj == null) {
+ if (obj == null)
return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
FileSystemObject other = (FileSystemObject) obj;
- if (this.mGroup == null) {
- if (other.mGroup != null) {
- return false;
- }
- } else if (!this.mGroup.equals(other.mGroup)) {
- return false;
- }
- if (this.mLastModifiedTime == null) {
- if (other.mLastModifiedTime != null) {
- return false;
- }
- } else if (!this.mLastModifiedTime.equals(other.mLastModifiedTime)) {
- return false;
- }
if (this.mName == null) {
- if (other.mName != null) {
+ if (other.mName != null)
return false;
- }
- } else if (!this.mName.equals(other.mName)) {
+ } else if (!this.mName.equals(other.mName))
return false;
- }
if (this.mParent == null) {
- if (other.mParent != null) {
- return false;
- }
- } else if (!this.mParent.equals(other.mParent)) {
- return false;
- }
- if (this.mPermissions == null) {
- if (other.mPermissions != null) {
+ if (other.mParent != null)
return false;
- }
- } else if (!this.mPermissions.equals(other.mPermissions)) {
- return false;
- }
- if (this.mResourceIconId != other.mResourceIconId) {
+ } else if (!this.mParent.equals(other.mParent))
return false;
- }
- if (this.mSize != other.mSize) {
- return false;
- }
- if (this.mUser == null) {
- if (other.mUser != null) {
- return false;
- }
- } else if (!this.mUser.equals(other.mUser)) {
- return false;
- }
return true;
}
@@ -354,23 +347,26 @@ public abstract class FileSystemObject implements Serializable, Comparable<FileS
*
* @return String The string representation
*/
- public String toRawString() {
+ public String toRawPermissionString() {
return String.format("%s%s", //$NON-NLS-1$
String.valueOf(getUnixIdentifier()),
getPermissions().toRawString());
}
- /**
- * {@inheritDoc}
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
*/
@Override
public String toString() {
- return "FileSystemObject [resourceIconId=" + this.mResourceIconId //$NON-NLS-1$
- + ", name=" + this.mName //$NON-NLS-1$
- + ", parent=" + this.mParent + ", user=" + this.mUser //$NON-NLS-1$ //$NON-NLS-2$
- + ", group=" + this.mGroup + ", permissions=" //$NON-NLS-1$ //$NON-NLS-2$
- + this.mPermissions + ", lastModifiedTime=" + this.mLastModifiedTime //$NON-NLS-1$
- + ", size=" + this.mSize + "]"; //$NON-NLS-1$//$NON-NLS-2$
+ return "FileSystemObject [mResourceIconId=" + this.mResourceIconId //$NON-NLS-1$
+ + ", mName=" + this.mName + ", mParent=" + this.mParent //$NON-NLS-1$ //$NON-NLS-2$
+ + ", mUser=" + this.mUser + ", mGroup=" + this.mGroup //$NON-NLS-1$ //$NON-NLS-2$
+ + ", mPermissions=" + this.mPermissions //$NON-NLS-1$
+ + ", mSize=" + this.mSize //$NON-NLS-1$
+ + ", mLastAccessedTime=" + this.mLastAccessedTime //$NON-NLS-1$
+ + ", mLastModifiedTime=" + this.mLastModifiedTime //$NON-NLS-1$
+ + ", mLastChangedTime=" + this.mLastChangedTime //$NON-NLS-1$
+ + "]"; //$NON-NLS-1$
}
}
diff --git a/src/com/cyanogenmod/filemanager/model/NamedPipe.java b/src/com/cyanogenmod/filemanager/model/NamedPipe.java
index 7899f9fa..5a15f850 100644
--- a/src/com/cyanogenmod/filemanager/model/NamedPipe.java
+++ b/src/com/cyanogenmod/filemanager/model/NamedPipe.java
@@ -25,7 +25,7 @@ import java.util.Date;
*/
public class NamedPipe extends SystemFile {
- private static final long serialVersionUID = -1847920531465352084L;
+ private static final long serialVersionUID = -5199356055601688190L;
/**
* The unix identifier of the object.
@@ -41,11 +41,15 @@ public class NamedPipe extends SystemFile {
* @param user The user proprietary of the object
* @param group The group proprietary of the object
* @param permissions The permissions of the object
+ * @param lastAccessedTime The last time that the object was accessed
* @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
*/
- public NamedPipe(String name, String parent, User user, Group group, Permissions permissions,
- Date lastModifiedTime) {
- super(name, parent, user, group, permissions, lastModifiedTime, 0L);
+ public NamedPipe(
+ String name, String parent, User user, Group group, Permissions permissions,
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime) {
+ super(name, parent, user, group, permissions, 0L,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
}
/**
diff --git a/src/com/cyanogenmod/filemanager/model/ParentDirectory.java b/src/com/cyanogenmod/filemanager/model/ParentDirectory.java
index f2a905b1..8a713791 100644
--- a/src/com/cyanogenmod/filemanager/model/ParentDirectory.java
+++ b/src/com/cyanogenmod/filemanager/model/ParentDirectory.java
@@ -24,7 +24,7 @@ import com.cyanogenmod.filemanager.util.FileHelper;
*/
public class ParentDirectory extends Directory {
- private static final long serialVersionUID = 4022696602271512681L;
+ private static final long serialVersionUID = -3818276335217197479L;
/**
* Constructor of <code>ParentDirectory</code>.
@@ -32,7 +32,7 @@ public class ParentDirectory extends Directory {
* @param parent The parent folder of the object
*/
public ParentDirectory(String parent) {
- super(FileHelper.PARENT_DIRECTORY, parent, null, null, null, null);
+ super(FileHelper.PARENT_DIRECTORY, parent, null, null, null, null, null, null);
}
/**
diff --git a/src/com/cyanogenmod/filemanager/model/RegularFile.java b/src/com/cyanogenmod/filemanager/model/RegularFile.java
index 7a3200e8..49c9fd77 100644
--- a/src/com/cyanogenmod/filemanager/model/RegularFile.java
+++ b/src/com/cyanogenmod/filemanager/model/RegularFile.java
@@ -23,7 +23,7 @@ import java.util.Date;
*/
public class RegularFile extends FileSystemObject {
- private static final long serialVersionUID = -6828866564538453913L;
+ private static final long serialVersionUID = 7113562456595400525L;
/**
* The unix identifier of the object.
@@ -39,12 +39,16 @@ public class RegularFile extends FileSystemObject {
* @param user The user proprietary of the object
* @param group The group proprietary of the object
* @param permissions The permissions of the object
- * @param lastModifiedTime The last time that the object was modified
* @param size The size in bytes of the object
+ * @param lastAccessedTime The last time that the object was accessed
+ * @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
*/
- public RegularFile(String name, String parent, User user, Group group, Permissions permissions,
- Date lastModifiedTime, long size) {
- super(name, parent, user, group, permissions, lastModifiedTime, size);
+ public RegularFile(String name, String parent, User user, Group group,
+ Permissions permissions, long size,
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime) {
+ super(name, parent, user, group, permissions, size,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
}
/**
diff --git a/src/com/cyanogenmod/filemanager/model/Symlink.java b/src/com/cyanogenmod/filemanager/model/Symlink.java
index b62e32fa..dc001810 100644
--- a/src/com/cyanogenmod/filemanager/model/Symlink.java
+++ b/src/com/cyanogenmod/filemanager/model/Symlink.java
@@ -25,7 +25,7 @@ import java.util.Date;
*/
public class Symlink extends FileSystemObject {
- private static final long serialVersionUID = 1354790574987082087L;
+ private static final long serialVersionUID = -6411787401264288389L;
/**
* The unix identifier of the object.
@@ -45,12 +45,15 @@ public class Symlink extends FileSystemObject {
* @param user The user proprietary of the object
* @param group The group proprietary of the object
* @param permissions The permissions of the object
+ * @param lastAccessedTime The last time that the object was accessed
* @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
*/
- public Symlink(
- String name, String link, String parent, User user,
- Group group, Permissions permissions, Date lastModifiedTime) {
- super(name, parent, user, group, permissions, lastModifiedTime, 0L);
+ public Symlink(String name, String link, String parent, User user,
+ Group group, Permissions permissions,
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime) {
+ super(name, parent, user, group, permissions, 0L,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
this.mLink = link;
}
diff --git a/src/com/cyanogenmod/filemanager/model/SystemFile.java b/src/com/cyanogenmod/filemanager/model/SystemFile.java
index 637fd536..7767452d 100644
--- a/src/com/cyanogenmod/filemanager/model/SystemFile.java
+++ b/src/com/cyanogenmod/filemanager/model/SystemFile.java
@@ -28,7 +28,7 @@ import java.util.Date;
*/
public abstract class SystemFile extends FileSystemObject {
- private static final long serialVersionUID = 1064161296325655096L;
+ private static final long serialVersionUID = -1396396017050697459L;
/**
* Constructor of <code>SystemFile</code>.
@@ -38,12 +38,16 @@ public abstract class SystemFile extends FileSystemObject {
* @param user The user proprietary of the object
* @param group The group proprietary of the object
* @param permissions The permissions of the object
- * @param lastModifiedTime The last time that the object was modified
* @param size The size in bytes of the object
+ * @param lastAccessedTime The last time that the object was accessed
+ * @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
*/
public SystemFile(
String name, String parent, User user, Group group,
- Permissions permissions, Date lastModifiedTime, long size) {
- super(name, parent, user, group, permissions, lastModifiedTime, size);
+ Permissions permissions, long size,
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime) {
+ super(name, parent, user, group, permissions, size,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
}
}
diff --git a/src/com/cyanogenmod/filemanager/preferences/Bookmarks.java b/src/com/cyanogenmod/filemanager/preferences/Bookmarks.java
index 74573754..998b7153 100644
--- a/src/com/cyanogenmod/filemanager/preferences/Bookmarks.java
+++ b/src/com/cyanogenmod/filemanager/preferences/Bookmarks.java
@@ -90,12 +90,20 @@ public class Bookmarks {
Bookmark.Columns.BOOKMARK_QUERY_COLUMNS,
null, null, null);
Bookmark bookmark = null;
- if (cursor != null) {
- if (cursor.moveToFirst()) {
- bookmark = new Bookmark(cursor);
+ try {
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ bookmark = new Bookmark(cursor);
+ }
}
- cursor.close();
+ } finally {
+ try {
+ if (cursor != null) {
+ cursor.close();
+ }
+ } catch (Exception e) {/**NON BLOCK**/}
}
+
return bookmark;
}
@@ -126,11 +134,19 @@ public class Bookmarks {
Bookmark.Columns.BOOKMARK_QUERY_COLUMNS,
where, new String[]{path}, null);
Bookmark bookmark = null;
- if (cursor != null) {
- if (cursor.moveToFirst()) {
- bookmark = new Bookmark(cursor);
+ try {
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ bookmark = new Bookmark(cursor);
+ }
+ cursor.close();
}
- cursor.close();
+ } finally {
+ try {
+ if (cursor != null) {
+ cursor.close();
+ }
+ } catch (Exception e) {/**NON BLOCK**/}
}
return bookmark;
}
diff --git a/src/com/cyanogenmod/filemanager/ui/dialogs/ActionsDialog.java b/src/com/cyanogenmod/filemanager/ui/dialogs/ActionsDialog.java
index 01ee26f5..ce03ed76 100644
--- a/src/com/cyanogenmod/filemanager/ui/dialogs/ActionsDialog.java
+++ b/src/com/cyanogenmod/filemanager/ui/dialogs/ActionsDialog.java
@@ -249,7 +249,7 @@ public class ActionsDialog implements OnItemClickListener, OnItemLongClickListen
//- Refresh
case R.id.mnu_actions_refresh:
if (this.mOnRequestRefreshListener != null) {
- this.mOnRequestRefreshListener.onRequestRefresh(null); //Refresh all
+ this.mOnRequestRefreshListener.onRequestRefresh(null, false); //Refresh all
}
break;
diff --git a/src/com/cyanogenmod/filemanager/ui/dialogs/FilesystemInfoDialog.java b/src/com/cyanogenmod/filemanager/ui/dialogs/FilesystemInfoDialog.java
index e6bf1116..d0786d10 100644
--- a/src/com/cyanogenmod/filemanager/ui/dialogs/FilesystemInfoDialog.java
+++ b/src/com/cyanogenmod/filemanager/ui/dialogs/FilesystemInfoDialog.java
@@ -180,7 +180,6 @@ public class FilesystemInfoDialog implements OnClickListener, OnCheckedChangeLis
//Gets text views
this.mSwStatus = (Switch)contentView.findViewById(R.id.filesystem_info_status);
- this.mSwStatus.setOnCheckedChangeListener(this);
TextView tvMountPoint =
(TextView)contentView.findViewById(R.id.filesystem_info_mount_point);
TextView tvDevice = (TextView)contentView.findViewById(R.id.filesystem_info_device);
@@ -240,6 +239,9 @@ public class FilesystemInfoDialog implements OnClickListener, OnCheckedChangeLis
this.mSwStatus.setEnabled(this.mIsMountAllowed);
this.mSwStatus.setChecked(MountPointHelper.isReadWrite(this.mMountPoint));
+ // Add the listener after set the value to avoid raising triggers
+ this.mSwStatus.setOnCheckedChangeListener(this);
+
//Change the tab
onClick(this.mInfoViewTab);
}
diff --git a/src/com/cyanogenmod/filemanager/ui/dialogs/FsoPropertiesDialog.java b/src/com/cyanogenmod/filemanager/ui/dialogs/FsoPropertiesDialog.java
index ecd44040..147682ce 100644
--- a/src/com/cyanogenmod/filemanager/ui/dialogs/FsoPropertiesDialog.java
+++ b/src/com/cyanogenmod/filemanager/ui/dialogs/FsoPropertiesDialog.java
@@ -297,8 +297,6 @@ public class FsoPropertiesDialog
String loadingMsg = this.mContext.getString(R.string.loading_message);
setSpinnerMsg(this.mContext, FsoPropertiesDialog.this.mSpnOwner, loadingMsg);
setSpinnerMsg(this.mContext, FsoPropertiesDialog.this.mSpnGroup, loadingMsg);
- this.mSpnOwner.setOnItemSelectedListener(this);
- this.mSpnGroup.setOnItemSelectedListener(this);
updatePermissions();
// Load owners and groups AIDs in background
@@ -333,6 +331,13 @@ public class FsoPropertiesDialog
this.mInfoMsgView.setOnClickListener(this);
}
+ // Add the listener after set the value to avoid raising triggers
+ this.mSpnOwner.setOnItemSelectedListener(this);
+ this.mSpnGroup.setOnItemSelectedListener(this);
+ setPermissionCheckBoxesListener(this.mChkUserPermission);
+ setPermissionCheckBoxesListener(this.mChkGroupPermission);
+ setPermissionCheckBoxesListener(this.mChkOthersPermission);
+
//Change the tab
onClick(this.mInfoViewTab);
this.mIgnoreCheckEvents = false;
@@ -805,7 +810,7 @@ public class FsoPropertiesDialog
* @param rootView The root view
* @return UserPermission The user permission
*/
- private CheckBox[] loadCheckBoxUserPermission (
+ private static CheckBox[] loadCheckBoxUserPermission (
Context ctx, View rootView, UserPermission permission) {
CheckBox[] chkPermissions = loadPermissionCheckBoxes(ctx, rootView, OWNER_TYPE);
chkPermissions[0].setChecked(permission.isSetUID());
@@ -820,7 +825,7 @@ public class FsoPropertiesDialog
* @param rootView The root view
* @return UserPermission The user permission
*/
- private CheckBox[] loadCheckBoxGroupPermission (
+ private static CheckBox[] loadCheckBoxGroupPermission (
Context ctx, View rootView, GroupPermission permission) {
CheckBox[] chkPermissions = loadPermissionCheckBoxes(ctx, rootView, GROUP_TYPE);
chkPermissions[0].setChecked(permission.isSetGID());
@@ -835,7 +840,7 @@ public class FsoPropertiesDialog
* @param rootView The root view
* @return UserPermission The user permission
*/
- private CheckBox[] loadCheckBoxOthersPermission (
+ private static CheckBox[] loadCheckBoxOthersPermission (
Context ctx, View rootView, OthersPermission permission) {
CheckBox[] chkPermissions = loadPermissionCheckBoxes(ctx, rootView, OTHERS_TYPE);
chkPermissions[0].setChecked(permission.isStickybit());
@@ -878,7 +883,7 @@ public class FsoPropertiesDialog
* @param type The type of permission [owner, group, others]
* @return CheckBox[] The checkboxes associated
*/
- private CheckBox[] loadPermissionCheckBoxes(Context ctx, View rootView, String type) {
+ private static CheckBox[] loadPermissionCheckBoxes(Context ctx, View rootView, String type) {
Resources res = ctx.getResources();
CheckBox[] chkPermissions = new CheckBox[4];
chkPermissions[0] = (CheckBox)rootView.findViewById(
@@ -897,11 +902,19 @@ public class FsoPropertiesDialog
ResourcesHelper.getIdentifier(
res, "id", //$NON-NLS-1$
String.format("fso_permissions_%s_special", type))); //$NON-NLS-1$
+ return chkPermissions;
+ }
+
+ /**
+ * Method that sets the listener for the permission checkboxes
+ *
+ * @param chkPermissions The checkboxes
+ */
+ private void setPermissionCheckBoxesListener(CheckBox[] chkPermissions) {
int cc = chkPermissions.length;
for (int i = 0; i < cc; i++) {
chkPermissions[i].setOnCheckedChangeListener(this);
}
- return chkPermissions;
}
/**
diff --git a/src/com/cyanogenmod/filemanager/ui/policy/CompressActionPolicy.java b/src/com/cyanogenmod/filemanager/ui/policy/CompressActionPolicy.java
index bdefe198..6e5f57fe 100644
--- a/src/com/cyanogenmod/filemanager/ui/policy/CompressActionPolicy.java
+++ b/src/com/cyanogenmod/filemanager/ui/policy/CompressActionPolicy.java
@@ -251,7 +251,7 @@ public final class CompressActionPolicy extends ActionsPolicy {
//Operation complete. Refresh
if (this.mOnRequestRefreshListener != null) {
// The reference is not the same, so refresh the complete navigation view
- this.mOnRequestRefreshListener.onRequestRefresh(null);
+ this.mOnRequestRefreshListener.onRequestRefresh(null, true);
}
if (this.cmd != null) {
showOperationSuccessMsg(
@@ -552,7 +552,7 @@ public final class CompressActionPolicy extends ActionsPolicy {
//Operation complete. Refresh
if (this.mOnRequestRefreshListener != null) {
// The reference is not the same, so refresh the complete navigation view
- this.mOnRequestRefreshListener.onRequestRefresh(null);
+ this.mOnRequestRefreshListener.onRequestRefresh(null, true);
}
if (this.cmd != null) {
showOperationSuccessMsg(
diff --git a/src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java b/src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java
index 75531480..1f583e96 100644
--- a/src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java
+++ b/src/com/cyanogenmod/filemanager/ui/policy/CopyMoveActionPolicy.java
@@ -305,7 +305,7 @@ public final class CopyMoveActionPolicy extends ActionsPolicy {
//Operation complete. Refresh
if (this.mOnRequestRefreshListener != null) {
// The reference is not the same, so refresh the complete navigation view
- this.mOnRequestRefreshListener.onRequestRefresh(null);
+ this.mOnRequestRefreshListener.onRequestRefresh(null, true);
}
ActionsPolicy.showOperationSuccessMsg(ctx);
}
diff --git a/src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java b/src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java
index 87c59afe..039f4fe8 100644
--- a/src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java
+++ b/src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java
@@ -196,9 +196,9 @@ public final class DeleteActionPolicy extends ActionsPolicy {
if (this.mOnRequestRefreshListener != null) {
// The reference is not the same, so refresh the complete navigation view
if (files != null && files.size() == 1) {
- this.mOnRequestRefreshListener.onRequestRemove(files.get(0));
+ this.mOnRequestRefreshListener.onRequestRemove(files.get(0), true);
} else {
- this.mOnRequestRefreshListener.onRequestRemove(null);
+ this.mOnRequestRefreshListener.onRequestRemove(null, true);
}
}
ActionsPolicy.showOperationSuccessMsg(ctx);
diff --git a/src/com/cyanogenmod/filemanager/ui/policy/InfoActionPolicy.java b/src/com/cyanogenmod/filemanager/ui/policy/InfoActionPolicy.java
index e7a4704d..ef4639b0 100644
--- a/src/com/cyanogenmod/filemanager/ui/policy/InfoActionPolicy.java
+++ b/src/com/cyanogenmod/filemanager/ui/policy/InfoActionPolicy.java
@@ -60,7 +60,7 @@ public final class InfoActionPolicy extends ActionsPolicy {
// Any change?
if (dialog.isHasChanged()) {
if (onRequestRefreshListener != null) {
- onRequestRefreshListener.onRequestRefresh(dialog.getFso());
+ onRequestRefreshListener.onRequestRefresh(dialog.getFso(), false);
}
}
}
diff --git a/src/com/cyanogenmod/filemanager/ui/policy/NewActionPolicy.java b/src/com/cyanogenmod/filemanager/ui/policy/NewActionPolicy.java
index 6f0bad95..b24cce11 100644
--- a/src/com/cyanogenmod/filemanager/ui/policy/NewActionPolicy.java
+++ b/src/com/cyanogenmod/filemanager/ui/policy/NewActionPolicy.java
@@ -110,7 +110,7 @@ public final class NewActionPolicy extends ActionsPolicy {
try {
fso = CommandHelper.getFileInfo(ctx, newName, false, null);
} catch (Throwable ex2) {/**NON BLOCK**/}
- onRequestRefreshListener.onRequestRefresh(fso);
+ onRequestRefreshListener.onRequestRefresh(fso, false);
}
showOperationSuccessMsg(ctx);
@@ -129,7 +129,7 @@ public final class NewActionPolicy extends ActionsPolicy {
try {
fso = CommandHelper.getFileInfo(ctx, newName, false, null);
} catch (Throwable ex2) {/**NON BLOCK**/}
- onRequestRefreshListener.onRequestRefresh(fso);
+ onRequestRefreshListener.onRequestRefresh(fso, false);
}
return Boolean.TRUE;
}
@@ -185,7 +185,7 @@ public final class NewActionPolicy extends ActionsPolicy {
} catch (Throwable ex2) {
/**NON BLOCK**/
}
- onRequestRefreshListener.onRequestRefresh(fso);
+ onRequestRefreshListener.onRequestRefresh(fso, false);
}
showOperationSuccessMsg(ctx);
@@ -204,7 +204,7 @@ public final class NewActionPolicy extends ActionsPolicy {
try {
fso = CommandHelper.getFileInfo(ctx, link, false, null);
} catch (Throwable ex2) {/**NON BLOCK**/}
- onRequestRefreshListener.onRequestRefresh(fso);
+ onRequestRefreshListener.onRequestRefresh(fso, false);
}
return Boolean.TRUE;
}
diff --git a/src/com/cyanogenmod/filemanager/ui/preferences/ThemeRoulette.java b/src/com/cyanogenmod/filemanager/ui/preferences/ThemeRoulette.java
index 3f401d48..c64169ce 100644
--- a/src/com/cyanogenmod/filemanager/ui/preferences/ThemeRoulette.java
+++ b/src/com/cyanogenmod/filemanager/ui/preferences/ThemeRoulette.java
@@ -16,13 +16,10 @@
package com.cyanogenmod.filemanager.ui.preferences;
-import android.app.Activity;
import android.content.Context;
import android.graphics.Paint;
-import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -279,11 +276,9 @@ public class ThemeRoulette extends HorizontalScrollView {
* @hide
*/
int getVisibleThemeViewPosition() {
- Display display = ((Activity)getContext()).getWindowManager().getDefaultDisplay();
- Point size = new Point();
- display.getSize(size);
-
- int x = size.x / 2;
+ int[] rouletteSize = new int[2];
+ this.getLocationOnScreen(rouletteSize);
+ int x = rouletteSize[0] + (this.getWidth() / 2);
int width = 0;
int[] location = new int[2];
diff --git a/src/com/cyanogenmod/filemanager/ui/preferences/ThemeSelectorPreference.java b/src/com/cyanogenmod/filemanager/ui/preferences/ThemeSelectorPreference.java
index 322bf8ce..bb70bfbd 100644
--- a/src/com/cyanogenmod/filemanager/ui/preferences/ThemeSelectorPreference.java
+++ b/src/com/cyanogenmod/filemanager/ui/preferences/ThemeSelectorPreference.java
@@ -38,6 +38,7 @@ import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.ui.ThemeManager;
import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
import com.cyanogenmod.filemanager.ui.preferences.ThemeRoulette.OnThemeScrollSelectionListener;
+import com.cyanogenmod.filemanager.util.AndroidHelper;
import com.cyanogenmod.filemanager.util.DialogHelper;
import java.util.ArrayList;
@@ -190,10 +191,15 @@ public class ThemeSelectorPreference extends Preference implements OnClickListen
display.getSize(size);
// Set the preference height
- int rowHeight = (int)res.getDimension(R.dimen.extra_margin);
+ int mh = (int)res.getDimension(R.dimen.theme_max_height);
+ int rowHeight = 0;
+ if (!AndroidHelper.isTablet(getContext())) {
+ rowHeight = (int)res.getDimension(R.dimen.extra_margin);
+ }
int[] window = new int[2];
view.getLocationInWindow(window);
- view.getLayoutParams().height = size.y - window[1] - rowHeight;
+ view.getLayoutParams().height =
+ Math.min(mh, size.y - window[1] - rowHeight);
// The button width
int minWidth = (int)res.getDimension(R.dimen.themes_min_width_button);
diff --git a/src/com/cyanogenmod/filemanager/ui/widgets/DirectoryInlineAutocompleteTextView.java b/src/com/cyanogenmod/filemanager/ui/widgets/DirectoryInlineAutocompleteTextView.java
index 498f017b..b674d98c 100644
--- a/src/com/cyanogenmod/filemanager/ui/widgets/DirectoryInlineAutocompleteTextView.java
+++ b/src/com/cyanogenmod/filemanager/ui/widgets/DirectoryInlineAutocompleteTextView.java
@@ -141,28 +141,25 @@ public class DirectoryInlineAutocompleteTextView
}
//Ensure data
- if (!value.startsWith(FileHelper.ROOT_DIRECTORY)) {
+ if (!value.startsWith(File.separator)) {
currentFilterData.clear();
this.mLastParent = ""; //$NON-NLS-1$
return;
}
//Get the new parent
- String newParent = new File(value).getParent();
- if (newParent == null) {
- newParent = FileHelper.ROOT_DIRECTORY;
+ String newParent = FileHelper.getParentDir(new File(value));
+ if (!newParent.endsWith(File.separator)) {
+ newParent += File.separator;
}
- if (!newParent.endsWith(FileHelper.ROOT_DIRECTORY)) {
- newParent += FileHelper.ROOT_DIRECTORY;
- }
- if (value.compareTo(FileHelper.ROOT_DIRECTORY) == 0) {
- newParent = FileHelper.ROOT_DIRECTORY;
+ if (value.compareTo(File.separator) == 0) {
+ newParent = File.separator;
currentFilterData.clear();
- } else if (value.endsWith(FileHelper.ROOT_DIRECTORY)) {
+ } else if (value.endsWith(File.separator)) {
//Force the change of parent
newParent = new File(value, "a").getParent(); //$NON-NLS-1$
- if (!newParent.endsWith(FileHelper.ROOT_DIRECTORY)) {
- newParent += FileHelper.ROOT_DIRECTORY;
+ if (!newParent.endsWith(File.separator)) {
+ newParent += File.separator;
}
currentFilterData.clear();
} else {
diff --git a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
index dd15c7ef..f6e71395 100644
--- a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
+++ b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
@@ -25,6 +25,9 @@ import android.os.storage.StorageVolume;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
@@ -835,15 +838,18 @@ public class NavigationView extends RelativeLayout implements
final List<FileSystemObject> files =
(List<FileSystemObject>)taskParams[0];
NavigationView.this.mAdapterView.post(
- new Runnable() {
- @Override
- public void run() {
- onPostExecuteTask(
- files, addToHistory,
- isNewHistory, hasChanged,
- searchInfo, fNewDir, scrollTo);
- }
- });
+ new Runnable() {
+ @Override
+ public void run() {
+ onPostExecuteTask(
+ files, addToHistory,
+ isNewHistory, hasChanged,
+ searchInfo, fNewDir, scrollTo);
+
+ // Do animation
+ fadeEfect(false);
+ }
+ });
return Boolean.TRUE;
}
@@ -857,10 +863,41 @@ public class NavigationView extends RelativeLayout implements
* {@inheritDoc}
*/
@Override
+ protected void onPreExecute() {
+ // Do animation
+ fadeEfect(true);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
protected void onPostExecute(List<FileSystemObject> files) {
- onPostExecuteTask(
- files, addToHistory, isNewHistory,
- hasChanged, searchInfo, fNewDir, scrollTo);
+ if (files != null) {
+ onPostExecuteTask(
+ files, addToHistory, isNewHistory,
+ hasChanged, searchInfo, fNewDir, scrollTo);
+
+ // Do animation
+ fadeEfect(false);
+ }
+ }
+
+ /**
+ * Method that performs a fade animation.
+ *
+ * @param out Fade out (true); Fade in (false)
+ */
+ void fadeEfect(boolean out) {
+ Animation fadeAnim = out ?
+ new AlphaAnimation(1, 0) :
+ new AlphaAnimation(0, 1);
+ fadeAnim.setDuration(50L);
+ fadeAnim.setFillAfter(true);
+ fadeAnim.setInterpolator(new AccelerateInterpolator());
+ NavigationView.this.startAnimation(fadeAnim);
}
};
task.execute(fNewDir);
@@ -1021,23 +1058,30 @@ public class NavigationView extends RelativeLayout implements
FileSystemObject fso = ((FileSystemObjectAdapter)parent.getAdapter()).getItem(position);
if (fso instanceof ParentDirectory) {
changeCurrentDir(fso.getParent(), true, false, false, null, null);
+ return;
} else if (fso instanceof Directory) {
changeCurrentDir(fso.getFullPath(), true, false, false, null, null);
+ return;
} else if (fso instanceof Symlink) {
Symlink symlink = (Symlink)fso;
if (symlink.getLinkRef() != null && symlink.getLinkRef() instanceof Directory) {
changeCurrentDir(
symlink.getLinkRef().getFullPath(), true, false, false, null, null);
+ return;
}
+
+ // Open the link ref
+ fso = symlink.getLinkRef();
+ }
+
+ // Open the file (edit or pick)
+ if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
+ // Open the file with the preferred registered app
+ IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null, null);
} else {
- if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
- // Open the file with the preferred registered app
- IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null, null);
- } else {
- // Request a file pick selection
- if (this.mOnFilePickedListener != null) {
- this.mOnFilePickedListener.onFilePicked(fso);
- }
+ // Request a file pick selection
+ if (this.mOnFilePickedListener != null) {
+ this.mOnFilePickedListener.onFilePicked(fso);
}
}
} catch (Throwable ex) {
@@ -1049,26 +1093,30 @@ public class NavigationView extends RelativeLayout implements
* {@inheritDoc}
*/
@Override
- public void onRequestRefresh(Object o) {
+ public void onRequestRefresh(Object o, boolean clearSelection) {
if (o instanceof FileSystemObject) {
refresh((FileSystemObject)o);
} else if (o == null) {
refresh();
}
- onDeselectAll();
+ if (clearSelection) {
+ onDeselectAll();
+ }
}
/**
* {@inheritDoc}
*/
@Override
- public void onRequestRemove(Object o) {
+ public void onRequestRemove(Object o, boolean clearSelection) {
if (o != null && o instanceof FileSystemObject) {
removeItem((FileSystemObject)o);
} else {
- onRequestRefresh(null);
+ onRequestRefresh(null, clearSelection);
+ }
+ if (clearSelection) {
+ onDeselectAll();
}
- onDeselectAll();
}
/**
diff --git a/src/com/cyanogenmod/filemanager/util/AIDHelper.java b/src/com/cyanogenmod/filemanager/util/AIDHelper.java
index 50b3efef..d49f1687 100644
--- a/src/com/cyanogenmod/filemanager/util/AIDHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/AIDHelper.java
@@ -97,19 +97,25 @@ public final class AIDHelper {
}
/**
- * Method that return AID from his user identifier
+ * Method that returns the AID from its identifier.
+ *
+ * @param id The id
+ * @return AID The AID, or null if not found
+ */
+ public static AID getAID(int id) {
+ return sAids.get(id);
+ }
+
+ /**
+ * Method that return AID from its user name.
*
- * @param ctx The current context
* @param name The user identifier
* @return AID The AID
*/
- public static AID getAIDFromName(Context ctx, String name) {
- // This method is only used by java console under chrooted mode, so
- // is safe to caching aids, because sdcards only allow known aids
- SparseArray<AID> aids = getAIDs(ctx, false);
- int len = aids.size();
+ public static AID getAIDFromName(String name) {
+ int len = sAids.size();
for (int i = 0; i < len; i++) {
- AID aid = aids.valueAt(i);
+ AID aid = sAids.valueAt(i);
if (aid.getName().compareTo(name) == 0) {
return aid;
}
@@ -117,4 +123,18 @@ public final class AIDHelper {
return new AID(-1, ""); //$NON-NLS-1$
}
+ /**
+ * Method that returns the name in safe way
+ *
+ * @param id The id
+ * @return String The name of the AID of null if not found
+ */
+ public static String getNullSafeName(int id) {
+ AID aid = getAID(id);
+ if (aid != null) {
+ return aid.getName();
+ }
+ return null;
+ }
+
}
diff --git a/src/com/cyanogenmod/filemanager/util/CommandHelper.java b/src/com/cyanogenmod/filemanager/util/CommandHelper.java
index 11b6f35f..f79cb9e9 100644
--- a/src/com/cyanogenmod/filemanager/util/CommandHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/CommandHelper.java
@@ -420,41 +420,6 @@ public final class CommandHelper {
}
/**
- * Method that retrieves the absolute path of a file or directory.
- *
- * @param context The current context (needed if console == null)
- * @param path The short path
- * @param console The console in which execute the program. <code>null</code>
- * to attach to the default console
- * @return String The absolute path of the directory
- * @throws FileNotFoundException If the initial directory not exists
- * @throws IOException If initial directory couldn't be checked
- * @throws InvalidCommandDefinitionException If the command has an invalid definition
- * @throws NoSuchFileOrDirectory If the file or directory was not found
- * @throws ConsoleAllocException If the console can't be allocated
- * @throws InsufficientPermissionsException If an operation requires elevated permissions
- * @throws CommandNotFoundException If the command was not found
- * @throws OperationTimeoutException If the operation exceeded the maximum time of wait
- * @throws ExecutionException If the operation returns a invalid exit code
- * @see ResolveLinkExecutable
- */
- public static String getAbsolutePath(Context context, String path, Console console)
- throws FileNotFoundException, IOException, ConsoleAllocException,
- NoSuchFileOrDirectory, InsufficientPermissionsException,
- CommandNotFoundException, OperationTimeoutException,
- ExecutionException, InvalidCommandDefinitionException {
- Console c = ensureConsole(context, console);
- ResolveLinkExecutable executable =
- c.getExecutableFactory().newCreator().createResolveLinkExecutable(path);
- execute(context, executable, c);
- FileSystemObject fso = executable.getResult();
- if (fso == null) {
- return null;
- }
- return fso.getFullPath();
- }
-
- /**
* Method that resolves a symlink to its real file system object.
*
* @param context The current context (needed if console == null)
diff --git a/src/com/cyanogenmod/filemanager/util/DialogHelper.java b/src/com/cyanogenmod/filemanager/util/DialogHelper.java
index 69960f8e..0dc9965c 100644
--- a/src/com/cyanogenmod/filemanager/util/DialogHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/DialogHelper.java
@@ -464,7 +464,9 @@ public final class DialogHelper {
R.layout.dialog_message,
null);
TextView vMsg = (TextView)lyMessage.findViewById(R.id.dialog_message);
- vMsg.setText(message);
+ // Dialog need to be filled with at least two lines to fill the background dialog,
+ // so we add a new additional line to the message
+ vMsg.setText(message + "\n"); //$NON-NLS-1$
// Apply the current theme
Theme theme = ThemeManager.getCurrentTheme(context);
diff --git a/src/com/cyanogenmod/filemanager/util/FileHelper.java b/src/com/cyanogenmod/filemanager/util/FileHelper.java
index abf4fed0..d4a2bb75 100644
--- a/src/com/cyanogenmod/filemanager/util/FileHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/FileHelper.java
@@ -16,7 +16,6 @@
package com.cyanogenmod.filemanager.util;
-import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
@@ -161,7 +160,6 @@ public final class FileHelper {
* @param size The size in bytes
* @return String The human readable size
*/
- @SuppressLint("DefaultLocale")
public static String getHumanReadableSize(long size) {
Resources res = FileManagerApplication.getInstance().getResources();
final String format = "%d %s"; //$NON-NLS-1$
@@ -220,6 +218,28 @@ public final class FileHelper {
}
/**
+ * Method that returns if the folder if the root directory.
+ *
+ * @param folder The folder
+ * @return boolean if the folder if the root directory
+ */
+ public static boolean isRootDirectory(String folder) {
+ if (folder == null) return true;
+ return isRootDirectory(new File(folder));
+ }
+
+ /**
+ * Method that returns if the folder if the root directory.
+ *
+ * @param folder The folder
+ * @return boolean if the folder if the root directory
+ */
+ public static boolean isRootDirectory(File folder) {
+ if (folder.getPath() == null) return true;
+ return folder.getPath().compareTo(FileHelper.ROOT_DIRECTORY) == 0;
+ }
+
+ /**
* Method that returns if the parent file system object if the root directory.
*
* @param fso The parent file system object to check
@@ -290,6 +310,30 @@ public final class FileHelper {
}
/**
+ * Method that returns the parent directory of a file/folder
+ *
+ * @param path The file/folder
+ * @return String The parent directory
+ */
+ public static String getParentDir(String path) {
+ return getParentDir(new File(path));
+ }
+
+ /**
+ * Method that returns the parent directory of a file/folder
+ *
+ * @param path The file/folder
+ * @return String The parent directory
+ */
+ public static String getParentDir(File path) {
+ String parent = path.getParent();
+ if (parent == null) {
+ parent = FileHelper.ROOT_DIRECTORY;
+ }
+ return parent;
+ }
+
+ /**
* Method that evaluates if a path is relative.
*
* @param src The path to check
@@ -735,6 +779,7 @@ public final class FileHelper {
* @return String The path with the trailing slash
*/
public static String addTrailingSlash(String path) {
+ if (path == null) return null;
return path.endsWith(File.separator) ? path : path + File.separator;
}
@@ -745,6 +790,7 @@ public final class FileHelper {
* @return String The path without the trailing slash
*/
public static String removeTrailingSlash(String path) {
+ if (path == null) return null;
if (path.trim().compareTo(ROOT_DIRECTORY) == 0) return path;
if (path.endsWith(File.separator)) {
return path.substring(0, path.length()-1);
@@ -870,11 +916,10 @@ public final class FileHelper {
/**
* Method that creates a {@link FileSystemObject} from a {@link File}
*
- * @param ctx The current context
* @param file The file or folder reference
* @return FileSystemObject The file system object reference
*/
- public static FileSystemObject createFileSystemObject(Context ctx, File file) {
+ public static FileSystemObject createFileSystemObject(File file) {
try {
// The user and group name of the files. In ChRoot, aosp give restrict access to
// this user and group.
@@ -885,20 +930,21 @@ public final class FileHelper {
// 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(ctx, USER);
- AID groupAID = AIDHelper.getAIDFromName(ctx, GROUP);
+ 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 = Permissions.fromRawString(PERMISSIONS);
// Build a directory?
+ Date lastModified = new Date(file.lastModified());
if (file.isDirectory()) {
return
new Directory(
file.getName(),
file.getParent(),
user, group, perm,
- new Date(file.lastModified()));
+ lastModified, lastModified, lastModified); // The only date we have
}
// Build a regular file
@@ -907,8 +953,8 @@ public final class FileHelper {
file.getName(),
file.getParent(),
user, group, perm,
- new Date(file.lastModified()),
- file.length());
+ file.length(),
+ lastModified, lastModified, lastModified); // The only date we have
} catch (Exception e) {
Log.e(TAG, "Exception retrieving the fso", e); //$NON-NLS-1$
}
diff --git a/src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java b/src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java
index 01637082..5a6f8689 100644
--- a/src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java
@@ -233,8 +233,13 @@ public final class MimeTypeHelper {
loadMimeTypes(context);
}
+ // Return the symlink ref mime/type icon
+ if (fso instanceof Symlink && ((Symlink) fso).getLinkRef() != null) {
+ return getIcon(context, ((Symlink) fso).getLinkRef());
+ }
+
//Check if the argument is a folder
- if (fso instanceof Directory || FileHelper.isSymlinkRefDirectory(fso)) {
+ if (fso instanceof Directory) {
return "ic_fso_folder_drawable"; //$NON-NLS-1$
}
@@ -264,7 +269,7 @@ public final class MimeTypeHelper {
return "fso_type_system_drawable"; //$NON-NLS-1$
}
// Check if the fso is executable (but not a symlink)
- if (!(fso instanceof Symlink)) {
+ if (fso.getPermissions() != null && !(fso instanceof Symlink)) {
if (fso.getPermissions().getUser().isExecute() ||
fso.getPermissions().getGroup().isExecute() ||
fso.getPermissions().getOthers().isExecute()) {
@@ -352,6 +357,35 @@ public final class MimeTypeHelper {
* Method that returns the mime/type category of the file.
*
* @param context The current context
+ * @param ext The extension of the file
+ * @return MimeTypeCategory The mime/type category
+ */
+ public static final MimeTypeCategory getCategoryFromExt(Context context, String ext) {
+ // Ensure that have a context
+ if (context == null && sMimeTypes == null) {
+ // No category
+ return MimeTypeCategory.NONE;
+ }
+ //Ensure that mime types are loaded
+ if (sMimeTypes == null) {
+ loadMimeTypes(context);
+ }
+ if (ext != null) {
+ //Load from the database of mime types
+ MimeTypeInfo mimeTypeInfo = sMimeTypes.get(ext.toLowerCase());
+ if (mimeTypeInfo != null) {
+ return mimeTypeInfo.mCategory;
+ }
+ }
+
+ // No category
+ return MimeTypeCategory.NONE;
+ }
+
+ /**
+ * Method that returns the mime/type category of the file.
+ *
+ * @param context The current context
* @param file The file
* @return MimeTypeCategory The mime/type category
*/
diff --git a/src/com/cyanogenmod/filemanager/util/MountPointHelper.java b/src/com/cyanogenmod/filemanager/util/MountPointHelper.java
index a91affac..e2e7b4c5 100644
--- a/src/com/cyanogenmod/filemanager/util/MountPointHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/MountPointHelper.java
@@ -36,13 +36,13 @@ public final class MountPointHelper {
private static final String TAG = "MountPointHelper"; //$NON-NLS-1$
- private static final List<String> ALLOWED_FS_TYPE = Arrays.asList(new String[]{
- "rootfs", //$NON-NLS-1$
- "tmpfs", //$NON-NLS-1$
- "vfat", //$NON-NLS-1$
- "ext2", //$NON-NLS-1$
- "ext3", //$NON-NLS-1$
- "ext4" //$NON-NLS-1$
+ private static final List<String> RESTRICTED_FS_TYPE = Arrays.asList(new String[]{
+ "devpts", //$NON-NLS-1$
+ "proc", //$NON-NLS-1$
+ "sysfs", //$NON-NLS-1$
+ "debugfs", //$NON-NLS-1$
+ "cgroup", //$NON-NLS-1$
+ "tmpfs" //$NON-NLS-1$
});
private static final long MAX_CACHED_TIME = 60000L * 5;
@@ -106,7 +106,7 @@ public final class MountPointHelper {
}
//Sort mount points in reverse order, needed for avoid
- //found an incorrect that matches the name
+ //found an incorrect mount point that matches the name
Collections.sort(sMountPoints, new Comparator<MountPoint>() {
@Override
public int compare(MountPoint lhs, MountPoint rhs) {
@@ -198,12 +198,12 @@ public final class MountPointHelper {
}
/**
- * Method that returns if the filesystem can be mounted.
+ * Method that returns if a filesystem is allowed to be mounted/unmounted (rw/ro).
*
* @param mp The mount point to check
- * @return boolean If the mount point can be mounted
+ * @return boolean If the mount point can be mounted/unmount (rw/ro)
*/
public static boolean isMountAllowed(MountPoint mp) {
- return ALLOWED_FS_TYPE.contains(mp.getType());
+ return !RESTRICTED_FS_TYPE.contains(mp.getType());
}
}
diff --git a/src/com/cyanogenmod/filemanager/util/ParseHelper.java b/src/com/cyanogenmod/filemanager/util/ParseHelper.java
index 43c4b6e7..ef619ac5 100644
--- a/src/com/cyanogenmod/filemanager/util/ParseHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/ParseHelper.java
@@ -16,8 +16,6 @@
package com.cyanogenmod.filemanager.util;
-import android.os.Process;
-
import com.cyanogenmod.filemanager.model.BlockDevice;
import com.cyanogenmod.filemanager.model.CharacterDevice;
import com.cyanogenmod.filemanager.model.Directory;
@@ -36,21 +34,68 @@ import com.cyanogenmod.filemanager.model.Symlink;
import com.cyanogenmod.filemanager.model.User;
import com.cyanogenmod.filemanager.model.UserPermission;
+import java.io.File;
import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.Date;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
/**
* A helper class with useful methods for deal with parse of results.
*/
public final class ParseHelper {
- private static final String DATE_PATTERN =
- "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}"; //$NON-NLS-1$
- private static final SimpleDateFormat DATE_FORMAT =
- new SimpleDateFormat("yyyy-MM-dd HH:mm"); //$NON-NLS-1$
+ // The structure of a terse stat output
+ // http://mailman.lug.org.uk/pipermail/nottingham/2007-January/009303.html
+ private static enum TERSE_STAT_STRUCT {
+ FILENAME,
+ SIZE,
+ BLOCKS,
+ RAW_MODE,
+ UID,
+ GID,
+ DEVICE,
+ INODE,
+ HARD_LINKS,
+ MAJOR_DEVICE_TYPE,
+ MINOR_DEVICE_TYPE,
+ ACCESS,
+ MODIFY,
+ CHANGE,
+ IOBLOCK
+ }
+ private static int TERSE_STAT_STRUCT_LENGTH = TERSE_STAT_STRUCT.values().length;
+
+ // The structure of raw mode in hex format (defined with octal values)
+ // http://unix.stackexchange.com/questions/39716/what-is-raw-mode-in-hex-from-stat-output
+ private static enum RMIHF {
+ S_IFMT (0170000), //bit mask for the file type bit fields
+ S_IFSOCK (0140000), //socket
+ S_IFLNK (0120000), //symbolic link
+ S_IFREG (0100000), //regular file
+ S_IFBLK (0060000), //block device
+ S_IFDIR (0040000), //directory
+ S_IFCHR (0020000), //character device
+ S_IFIFO (0010000), //FIFO
+ S_ISUID (0004000), //set UID bit
+ S_ISGID (0002000), //set-group-ID bit (see below)
+ S_ISVTX (0001000), //sticky bit (see below)
+ S_IRWXU (0000700), //mask for file owner permissions
+ S_IRUSR (0000400), //owner has read permission
+ S_IWUSR (0000200), //owner has write permission
+ S_IXUSR (0000100), //owner has execute permission
+ S_IRWXG (0000070), //mask for group permissions
+ S_IRGRP (0000040), //group has read permission
+ S_IWGRP (0000020), //group has write permission
+ S_IXGRP (0000010), //group has execute permission
+ S_IRWXO (0000007), //mask for permissions for others (not in group)
+ S_IROTH (0000004), //others have read permission
+ S_IWOTH (0000002), //others have write permission
+ S_IXOTH (0000001); //others have execute permission
+
+ final int mValue;
+ RMIHF(int value) {
+ this.mValue = value;
+ }
+ }
/**
* Constructor of <code>ParseHelper</code>.
@@ -60,166 +105,105 @@ public final class ParseHelper {
}
/**
- * Method that parses and creates a {@link FileSystemObject} references from
- * a unix string style line.
+ * Method that parses the output of a terse stat command.<br/>
+ * <br/>
+ * The stat terse format is described as:<br/>
+ * <br/>
+ * <code/>
+ * terse format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o":
+ * filename
+ * size(bytes)
+ * blocks
+ * Raw_mode(HEX)
+ * Uid
+ * Gid
+ * Device(HEX)
+ * Inode
+ * hard_links
+ * major_device_type(HEX)
+ * minor_device_type(HEX)
+ * Access(Epoch seconds)
+ * Modify(Epoch seconds)
+ * Change(Epoch seconds)
+ * IOblock
+ * </code>
*
- * @param parent The parent of the object
- * @param src The unix string style line
+ * @param output Line with the output of a line of a stat command
* @return FileSystemObject The file system object reference
- * @throws ParseException If the line can't be parsed
- * @see #toFileSystemObject(String, String, boolean)
+ * @throws ParseException If the permissions can't be parsed
+ * @{link "http://www.gnu.org/software/coreutils/manual/html_node/stat-invocation.html"}
*/
- public static FileSystemObject toFileSystemObject(
- final String parent, final String src) throws ParseException {
- return toFileSystemObject(parent, src, false);
- }
+ public static FileSystemObject parseStatOutput(final String output) throws ParseException {
- /**
- * Method that parses and creates a {@link FileSystemObject} references from
- * a unix string style line.
- *
- * @param parent The parent of the object
- * @param src The unix string style line
- * @param quick Do not resolve data (User and Group doesn't have a valid reference)
- * @return FileSystemObject The file system object reference
- * @throws ParseException If the line can't be parsed
- */
- //
- //<permission> <user> <group> <size> <last modified> <name>
- //-rw-r--r-- root root 229 2012-05-04 01:51 boot.txt
- //drwxr-xr-x root root 2012-05-04 01:51 acct
- //lrwxrwxrwx root root 2012-05-04 01:51 etc -> /system/etc
- //crw-rw-rw- system system 10, 243 2012-05-04 01:51 HPD
- //brw------- root root 7, 0 2012-05-04 01:51 loop0
- //srw------- root root 0 2012-05-04 01:51 socket
- //prw------- root root 0 2012-05-04 01:51 pipe
- //
- //
- //<permissions>: http://en.wikipedia.org/wiki/File_system_permissions
- //-rw-r--r--
- //
- //(char 1)
- // - denotes a regular file
- // d denotes a directory
- // b denotes a block special file
- // c denotes a character special file
- // l denotes a symbolic link
- // p denotes a named pipe
- // s denotes a domain socket
- //(char 2-10)
- // r if the read bit is set, - if it is not.
- // w if the write bit is set, - if it is not.
- // x if the execute bit is set, - if it is not.
- //(char 4)
- // s if the setuid bit and executable bit are set
- // S if the setuid bit is set, but not executable bit
- //(char 7)
- // s if the setgid bit and executable bit are set
- // S if the setgid bit is set, but not executable bit
- //(char 10)
- // t if the sticky bit and executable bit are set
- // T if the sticky bit is set, but not executable bit
- //
- //<user>: User proprietary of the file
- //<group>: Group proprietary of the file
- //<last modified>:
- //<size>:
- // - if object is a type regular file, size of the file in bytes
- // - if object is a block or a character device, mayor and minor device number (7, 0)
- // - if object is a pipe or a socket, always is 0
- // - if object is a directory or symlink, no value is present
- //
- //<last modification>: Last file modification (in Android always yyyy-MM-dd HH:mm.
- // Can ensure this?)
- //<name>:
- // - if object is a symlink, the value must be "link name -> real name"
- // - If the name is void, then assume that it is the root directory (/)
- //
- public static FileSystemObject toFileSystemObject(
- final String parent, final String src, final boolean quick) throws ParseException {
-
- String raw = src;
-
- //0.- Object Type
- char type = raw.charAt(0);
-
- //1.- Extract permissions
- String szPermissions = raw.substring(0, 10);
- Permissions oPermissions = parsePermission(szPermissions);
- raw = raw.substring(11);
-
- //2.- Extract the last modification date
- Pattern pattern = Pattern.compile(DATE_PATTERN);
- Matcher matcher = pattern.matcher(raw);
- if (!matcher.find()) {
- throw new ParseException(
- "last modification date not found in " + raw, 0); //$NON-NLS-1$
- }
- Date dLastModified = null;
try {
- dLastModified = DATE_FORMAT.parse(matcher.group());
- } catch (ParseException pEx) {
- throw new ParseException(pEx.getMessage(), 0);
- }
- String szStartLine = raw.substring(0, matcher.start()).trim();
- String szEndLine = raw.substring(matcher.end()).trim();
-
- //3.- Extract user (user name has no spaces.
- int pos = szStartLine.indexOf(" "); //$NON-NLS-1$
- String szUser = szStartLine.substring(0, pos).trim();
- szStartLine = szStartLine.substring(pos).trim();
- User oUser = null;
- if (!quick) {
- oUser = new User(Process.getUidForName(szUser), szUser);
- } else {
- oUser = new User(-1, szUser);
- }
-
- //4.- Extract group (group name has no spaces.
- pos = szStartLine.indexOf(" "); //$NON-NLS-1$
- String szGroup = szStartLine.substring(0, (pos == -1) ? szStartLine.length() : pos).trim();
- szStartLine = szStartLine.substring((pos == -1) ? szStartLine.length() : pos).trim();
- Group oGroup = null;
- if (!quick) {
- oGroup = new Group(Process.getGidForName(szGroup), szGroup);
- } else {
- oGroup = new Group(-1, szGroup);
- }
-
- //5.- Extract size
- long lSize = 0;
- if (szStartLine.length() != 0) {
- //At this moment only size of files is interesting. Mayor/minor block
- //devices are no required
- if (type == RegularFile.UNIX_ID) {
- try {
- lSize = Long.parseLong(szStartLine);
- } catch (NumberFormatException nfEx) {
- throw new ParseException(nfEx.getMessage(), 0);
- }
+ // Split the terse line
+ String[] data = output.split(" "); //$NON-NLS-1$
+ boolean valid = true;
+ try {
+ getTerseStatInt(data, TERSE_STAT_STRUCT.IOBLOCK);
+ } catch (Exception e) {
+ valid = false;
+ }
+ if (valid && output.startsWith("stat:")) { //$NON-NLS-1$
+ throw new ParseException(
+ String.format("Stat failed: %s", output), 0); //$NON-NLS-1$
+ }
+ if (valid && data.length < TERSE_STAT_STRUCT.values().length) {
+ throw new ParseException(
+ String.format("Not enought data: %s", output), 0); //$NON-NLS-1$
+ }
+ // Parse the line
+ String raw = getTerseRawPermissions(data);
+ char type = raw.charAt(0);
+ Permissions permissions = parsePermission(raw);
+ Date lastAccessedTime = getTerseStatDate(data, TERSE_STAT_STRUCT.ACCESS);
+ Date lastModifiedTime = getTerseStatDate(data, TERSE_STAT_STRUCT.MODIFY);
+ Date lastChangedTime = getTerseStatDate(data, TERSE_STAT_STRUCT.CHANGE);
+ int uid = getTerseStatInt(data, TERSE_STAT_STRUCT.UID);
+ User user = new User(uid, AIDHelper.getNullSafeName(uid));
+ int gid = getTerseStatInt(data, TERSE_STAT_STRUCT.GID);
+ Group group = new Group(gid, AIDHelper.getNullSafeName(gid));
+ long size = getTerseStatLong(data, TERSE_STAT_STRUCT.SIZE);
+ File file = new File(getTerseStatName(data));
+ String name = file.getName();
+ String parentDir = FileHelper.getParentDir(file);
+
+ // Create the file system object
+ FileSystemObject fso =
+ createObject(
+ parentDir, type, name, null, user, group, permissions,
+ size, lastAccessedTime, lastModifiedTime, lastChangedTime);
+
+ // Check if its a symlink
+ if (type == Symlink.UNIX_ID) {
+ // Extract the ref info
+ Symlink symlink = (Symlink)fso;
+ File refFile = file.getCanonicalFile();
+ char refType = refFile.isDirectory() ? Directory.UNIX_ID : RegularFile.UNIX_ID;
+ String refName = refFile.getName();
+ String refParentDir = FileHelper.getParentDir(refFile);
+ Date refLastModifiedTime = new Date(refFile.lastModified());
+ long refSize = refFile.length();
+
+ // Create the ref file system object
+ FileSystemObject refFso =
+ createObject(
+ refParentDir, refType, refName, null, null, null, null,
+ refSize, null, refLastModifiedTime, null);
+
+ // Update the symlink ref
+ symlink.setLink(refParentDir);
+ symlink.setLinkRef(refFso);
}
- }
- //6.- Extract object name
- String szName = szEndLine;
- if (szName.trim().length() == 0) {
- // Assume that the object name is the root folder
- szName = FileHelper.ROOT_DIRECTORY;
- }
- String szLink = null;
- if (type == Symlink.UNIX_ID) {
- //"link name -> real name"
- String[] names = szEndLine.split(" -> "); //$NON-NLS-1$
- szName = names[0].trim();
- szLink = names[1].trim();
- }
+ // Parsed
+ return fso;
- // All the line is parsed now. Create the object
- FileSystemObject fso = createObject(
- parent, type, szName, szLink, oUser, oGroup,
- oPermissions, dLastModified, lSize);
- return fso;
+ } catch (Exception ex) {
+ // Notify the exception when parsing the data
+ throw new ParseException(ex.getMessage(), 0);
+ }
}
/**
@@ -259,64 +243,19 @@ public final class ParseHelper {
}
/**
- * Method that creates the appropriate file system object.
- *
- * @param parentDir The parent directory
- * @param type The raw char type of the file system object
- * @param name The name of the object
- * @param link The real file that this symlink is point to
- * @param user The user proprietary of the object
- * @param group The group proprietary of the object
- * @param permissions The permissions of the object
- * @param lastModifiedTime The last time that the object was modified
- * @param size The size in bytes of the object
- * @return FileSystemObject The file system object reference
- * @throws ParseException If type couldn't be translate into a reference
- * file system object
- */
- private static FileSystemObject createObject(
- String parentDir, char type, String name, String link, User user,
- Group group, Permissions permissions, Date lastModifiedTime, long size)
- throws ParseException {
-
- if (type == RegularFile.UNIX_ID) {
- return new RegularFile(
- name, parentDir, user, group, permissions, lastModifiedTime, size);
- }
- if (type == Directory.UNIX_ID) {
- return new Directory(name, parentDir, user, group, permissions, lastModifiedTime);
- }
- if (type == Symlink.UNIX_ID) {
- return new Symlink(name, link, parentDir, user, group, permissions, lastModifiedTime);
- }
- if (type == BlockDevice.UNIX_ID) {
- return new BlockDevice(name, parentDir, user, group, permissions, lastModifiedTime);
- }
- if (type == CharacterDevice.UNIX_ID) {
- return new CharacterDevice(name, parentDir, user, group, permissions, lastModifiedTime);
- }
- if (type == NamedPipe.UNIX_ID) {
- return new NamedPipe(name, parentDir, user, group, permissions, lastModifiedTime);
- }
- if (type == DomainSocket.UNIX_ID) {
- return new DomainSocket(name, parentDir, user, group, permissions, lastModifiedTime);
- }
- throw new ParseException("no file system object", 0); //$NON-NLS-1$
- }
-
- /**
* Method that parse a disk usage line.
*
* @param src The disk usage line
* @return DiskUsage The disk usage information
* @throws ParseException If the line can't be parsed
*/
- // Filesystem Size Used Free Blksize
- // /dev 414M 48K 414M 4096
- // /mnt/asec 414M 0K 414M 4096
- // /mnt/secure/asec: Permission denied
public static DiskUsage toDiskUsage(final String src) throws ParseException {
+ // Filesystem Size Used Free Blksize
+ // /dev 414M 48K 414M 4096
+ // /mnt/asec 414M 0K 414M 4096
+ // /mnt/secure/asec: Permission denied
+
try {
final int fields = 5;
@@ -351,14 +290,13 @@ public final class ParseHelper {
* @return MountPoint The mount point information
* @throws ParseException If the line can't be parsed
*/
- // rootfs / rootfs ro,relatime 0 0
- // tmpfs /dev tmpfs rw,nosuid,relatime,mode=755 0 0
- // devpts /dev/pts devpts rw,relatime,mode=600 0 0
- // /dev/block/vold/179:25 /mnt/emmc vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000, \
- // gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1, \
- // shortname=mixed,utf8,errors=remount-ro 0 0
public static MountPoint toMountPoint(final String src) throws ParseException {
+ // rootfs / rootfs ro,relatime 0 0
+ // tmpfs /dev tmpfs rw,nosuid,relatime,mode=755 0 0
+ // devpts /dev/pts devpts rw,relatime,mode=600 0 0
+ // /dev/block/vold/179:25 /mnt/emmc vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000, gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1, shortname=mixed,utf8,errors=remount-ro 0 0
+
try {
//Extract all the info
@@ -389,6 +327,64 @@ public final class ParseHelper {
}
/**
+ * Method that creates the appropriate file system object.
+ *
+ * @param parentDir The parent directory
+ * @param type The raw char type of the file system object
+ * @param name The name of the object
+ * @param link The real file that this symlink is point to
+ * @param user The user proprietary of the object
+ * @param group The group proprietary of the object
+ * @param permissions The permissions of the object
+ * @param size The size in bytes of the object
+ * @param lastAccessedTime The last time that the object was accessed
+ * @param lastModifiedTime The last time that the object was modified
+ * @param lastChangedTime The last time that the object was changed
+ * @return FileSystemObject The file system object reference
+ * @throws ParseException If type couldn't be translate into a reference
+ * file system object
+ */
+ private static FileSystemObject createObject(
+ String parentDir, char type, String name, String link, User user,
+ Group group, Permissions permissions, long size,
+ Date lastAccessedTime, Date lastModifiedTime, Date lastChangedTime)
+ throws ParseException {
+
+ String parent = (parentDir == null) ? FileHelper.ROOT_DIRECTORY : parentDir;
+
+ if (type == RegularFile.UNIX_ID) {
+ return new RegularFile(
+ name, parent, user, group, permissions, size,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
+ }
+ if (type == Directory.UNIX_ID) {
+ return new Directory(name, parent, user, group, permissions,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
+ }
+ if (type == Symlink.UNIX_ID) {
+ return new Symlink(name, link, parent, user, group, permissions,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
+ }
+ if (type == BlockDevice.UNIX_ID) {
+ return new BlockDevice(name, parent, user, group, permissions,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
+ }
+ if (type == CharacterDevice.UNIX_ID) {
+ return new CharacterDevice(name, parent, user, group, permissions,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
+ }
+ if (type == NamedPipe.UNIX_ID) {
+ return new NamedPipe(name, parent, user, group, permissions,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
+ }
+ if (type == DomainSocket.UNIX_ID) {
+ return new DomainSocket(name, parent, user, group, permissions,
+ lastAccessedTime, lastModifiedTime, lastChangedTime);
+ }
+ throw new ParseException("no file system object", 0); //$NON-NLS-1$
+ }
+
+ /**
* Method that converts to bytes the string representation
* of a size (10M, 1G, 0K, ...).
*
@@ -396,20 +392,140 @@ public final class ParseHelper {
* @return long The size in bytes
*/
private static long toBytes(String size) {
- long bytes = Long.parseLong(size.substring(0, size.length() - 1));
+ double bytes = Double.parseDouble(size.substring(0, size.length() - 1));
String unit = size.substring(size.length() - 1);
if (unit.compareToIgnoreCase("G") == 0) { //$NON-NLS-1$
- return bytes * 1024 * 1024 * 1024;
+ return (long)(bytes * 1024 * 1024 * 1024);
}
if (unit.compareToIgnoreCase("M") == 0) { //$NON-NLS-1$
- return bytes * 1024 * 1024;
+ return (long)(bytes * 1024 * 1024);
}
if (unit.compareToIgnoreCase("K") == 0) { //$NON-NLS-1$
- return bytes * 1024;
+ return (long)(bytes * 1024);
}
//Don't touch
- return bytes;
+ return (long)bytes;
+ }
+
+ /**
+ * Method that extract a date from a terse stat ouput.
+ *
+ * @param stat The terse stat data
+ * @param e The position of the date
+ * @return Date The date
+ */
+ private static Date getTerseStatDate(String[] stat, TERSE_STAT_STRUCT e) {
+ int cc = stat.length;
+ return new Date(
+ Long.parseLong(stat[cc - (TERSE_STAT_STRUCT_LENGTH - e.ordinal())]) * 1000L);
+ }
+
+ /**
+ * Method that extract a integer value from a terse stat ouput.
+ *
+ * @param stat The terse stat data
+ * @param e The position of the date
+ * @return int The integer value
+ */
+ private static int getTerseStatInt(String[] stat, TERSE_STAT_STRUCT e) {
+ int cc = stat.length;
+ return Integer.parseInt(stat[cc - (TERSE_STAT_STRUCT_LENGTH - e.ordinal())]);
+ }
+
+ /**
+ * Method that extract a long value from a terse stat ouput.
+ *
+ * @param stat The terse stat data
+ * @param e The position of the date
+ * @return long The long value
+ */
+ private static long getTerseStatLong(String[] stat, TERSE_STAT_STRUCT e) {
+ int cc = stat.length;
+ return Long.parseLong(stat[cc - (TERSE_STAT_STRUCT_LENGTH - e.ordinal())]);
+ }
+
+ /**
+ * Method that returns the name of file
+ *
+ * @param stat The terse stat data
+ * @return String The name of file
+ */
+ private static String getTerseStatName(String[] stat) {
+ int cc = stat.length;
+ int to = cc - (TERSE_STAT_STRUCT_LENGTH - TERSE_STAT_STRUCT.SIZE.ordinal());
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < to; i++) {
+ sb.append(stat[i]);
+ if (i < to-1) {
+ sb.append(" "); //$NON-NLS-1$
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Method that retrieve the raw string with the permissions.
+ *
+ * @param stat The terse stat data
+ * @return String The raw string
+ */
+ private static String getTerseRawPermissions(String[] stat) {
+ int cc = stat.length;
+ int rawInt = Integer.parseInt(
+ stat[cc - (TERSE_STAT_STRUCT_LENGTH - TERSE_STAT_STRUCT.RAW_MODE.ordinal())],16);
+
+ // Extract the type
+ char t = RegularFile.UNIX_ID;
+ if (RMIHF.S_IFSOCK.mValue == (rawInt & RMIHF.S_IFSOCK.mValue)) {
+ t = DomainSocket.UNIX_ID;
+ } else if (RMIHF.S_IFLNK.mValue == (rawInt & RMIHF.S_IFLNK.mValue)) {
+ t = Symlink.UNIX_ID;
+ } else if (RMIHF.S_IFREG.mValue == (rawInt & RMIHF.S_IFREG.mValue)) {
+ t = RegularFile.UNIX_ID;
+ } else if (RMIHF.S_IFBLK.mValue == (rawInt & RMIHF.S_IFBLK.mValue)) {
+ t = BlockDevice.UNIX_ID;
+ } else if (RMIHF.S_IFDIR.mValue == (rawInt & RMIHF.S_IFDIR.mValue)) {
+ t = Directory.UNIX_ID;
+ } else if (RMIHF.S_IFCHR.mValue == (rawInt & RMIHF.S_IFCHR.mValue)) {
+ t = CharacterDevice.UNIX_ID;
+ } else if (RMIHF.S_IFIFO.mValue == (rawInt & RMIHF.S_IFIFO.mValue)) {
+ t = NamedPipe.UNIX_ID;
+ }
+
+ // Extract User/Group/Others
+ boolean us = RMIHF.S_ISUID.mValue == (rawInt & RMIHF.S_ISUID.mValue);
+ boolean ur = RMIHF.S_IRUSR.mValue == (rawInt & RMIHF.S_IRUSR.mValue);
+ boolean uw = RMIHF.S_IWUSR.mValue == (rawInt & RMIHF.S_IWUSR.mValue);
+ boolean ux = RMIHF.S_IXUSR.mValue == (rawInt & RMIHF.S_IXUSR.mValue);
+ boolean gs = RMIHF.S_ISGID.mValue == (rawInt & RMIHF.S_ISGID.mValue);
+ boolean gr = RMIHF.S_IRGRP.mValue == (rawInt & RMIHF.S_IRGRP.mValue);
+ boolean gw = RMIHF.S_IWGRP.mValue == (rawInt & RMIHF.S_IWGRP.mValue);
+ boolean gx = RMIHF.S_IXGRP.mValue == (rawInt & RMIHF.S_IXGRP.mValue);
+ boolean os = RMIHF.S_ISVTX.mValue == (rawInt & RMIHF.S_ISVTX.mValue);
+ boolean or = RMIHF.S_IROTH.mValue == (rawInt & RMIHF.S_IROTH.mValue);
+ boolean ow = RMIHF.S_IWOTH.mValue == (rawInt & RMIHF.S_IWOTH.mValue);
+ boolean ox = RMIHF.S_IXOTH.mValue == (rawInt & RMIHF.S_IXOTH.mValue);
+
+ // Build the raw string
+ StringBuilder sb = new StringBuilder();
+ sb.append(t);
+ sb.append(ur ? Permission.READ : Permission.UNASIGNED);
+ sb.append(uw ? Permission.WRITE : Permission.UNASIGNED);
+ sb.append(us ? (ux ?
+ UserPermission.SETUID_E : UserPermission.SETUID)
+ : (ux ? Permission.EXECUTE : Permission.UNASIGNED));
+ sb.append(gr ? Permission.READ : Permission.UNASIGNED);
+ sb.append(gw ? Permission.WRITE : Permission.UNASIGNED);
+ sb.append(gs ? (gx ?
+ GroupPermission.SETGID_E : GroupPermission.SETGID)
+ : (gx ? Permission.EXECUTE : Permission.UNASIGNED));
+ sb.append(or ? Permission.READ : Permission.UNASIGNED);
+ sb.append(ow ? Permission.WRITE : Permission.UNASIGNED);
+ sb.append(os ? (ox ?
+ OthersPermission.STICKY_E : OthersPermission.STICKY)
+ : (ox ? Permission.EXECUTE : Permission.UNASIGNED));
+ return sb.toString();
}
}
diff --git a/tests/src/com/cyanogenmod/filemanager/commands/shell/CompressCommandTest.java b/tests/src/com/cyanogenmod/filemanager/commands/shell/CompressCommandTest.java
index 2c02732e..dc46d6a9 100644
--- a/tests/src/com/cyanogenmod/filemanager/commands/shell/CompressCommandTest.java
+++ b/tests/src/com/cyanogenmod/filemanager/commands/shell/CompressCommandTest.java
@@ -138,21 +138,26 @@ public class CompressCommandTest extends AbstractConsoleTest {
CompressExecutable cmd =
CommandHelper.compress(
getContext(), mode, dst, ARCHIVE_DATA, new AsyncResultListener() {
+ @Override
public void onAsyncStart() {
/**NON BLOCK**/
}
+ @Override
public void onAsyncEnd(boolean cancelled) {
synchronized (CompressCommandTest.this.mSync) {
CompressCommandTest.this.mNormalEnd = true;
CompressCommandTest.this.mSync.notify();
}
}
+ @Override
public void onAsyncExitCode(int exitCode) {
/**NON BLOCK**/
}
+ @Override
public void onException(Exception cause) {
fail(String.valueOf(cause));
}
+ @Override
public void onPartialResult(Object result) {
CompressCommandTest.this.mNewPartialData = true;
Log.d(TAG, (String)result);
@@ -199,21 +204,26 @@ public class CompressCommandTest extends AbstractConsoleTest {
cmd =
CommandHelper.compress(
getContext(), mode, COMPRESS_DATA_DST, new AsyncResultListener() {
+ @Override
public void onAsyncStart() {
/**NON BLOCK**/
}
+ @Override
public void onAsyncEnd(boolean cancelled) {
synchronized (CompressCommandTest.this.mSync) {
CompressCommandTest.this.mNormalEnd = true;
CompressCommandTest.this.mSync.notify();
}
}
+ @Override
public void onAsyncExitCode(int exitCode) {
/**NON BLOCK**/
}
+ @Override
public void onException(Exception cause) {
fail(String.valueOf(cause));
}
+ @Override
public void onPartialResult(Object result) {
CompressCommandTest.this.mNewPartialData = true;
Log.d(TAG, (String)result);
diff --git a/tests/src/com/cyanogenmod/filemanager/commands/shell/ExecCommandTest.java b/tests/src/com/cyanogenmod/filemanager/commands/shell/ExecCommandTest.java
index 7cfd0964..a456c059 100644
--- a/tests/src/com/cyanogenmod/filemanager/commands/shell/ExecCommandTest.java
+++ b/tests/src/com/cyanogenmod/filemanager/commands/shell/ExecCommandTest.java
@@ -16,8 +16,6 @@
package com.cyanogenmod.filemanager.commands.shell;
-import java.io.OutputStream;
-
import android.os.Environment;
import android.test.suitebuilder.annotation.MediumTest;
@@ -26,6 +24,8 @@ import com.cyanogenmod.filemanager.commands.WriteExecutable;
import com.cyanogenmod.filemanager.model.Permissions;
import com.cyanogenmod.filemanager.util.CommandHelper;
+import java.io.OutputStream;
+
/**
* A class for testing exec command.
*
@@ -81,20 +81,25 @@ public class ExecCommandTest extends AbstractConsoleTest {
// Execute the test program
this.mNewPartialData = false;
CommandHelper.exec(getContext(), EXEC_CMD, new AsyncResultListener() {
+ @Override
public void onAsyncStart() {
/**NON BLOCK**/
}
+ @Override
public void onAsyncEnd(boolean cancelled) {
synchronized (ExecCommandTest.this.mSync) {
ExecCommandTest.this.mSync.notify();
}
}
+ @Override
public void onAsyncExitCode(int exitCode) {
/**NON BLOCK**/
}
+ @Override
public void onException(Exception cause) {
fail(String.valueOf(cause));
}
+ @Override
public void onPartialResult(Object results) {
ExecCommandTest.this.mNewPartialData = true;
}
diff --git a/tests/src/com/cyanogenmod/filemanager/commands/shell/FindCommandTest.java b/tests/src/com/cyanogenmod/filemanager/commands/shell/FindCommandTest.java
index 46ce9daa..d12b69e4 100644
--- a/tests/src/com/cyanogenmod/filemanager/commands/shell/FindCommandTest.java
+++ b/tests/src/com/cyanogenmod/filemanager/commands/shell/FindCommandTest.java
@@ -16,9 +16,6 @@
package com.cyanogenmod.filemanager.commands.shell;
-import java.util.ArrayList;
-import java.util.List;
-
import android.os.Environment;
import android.test.suitebuilder.annotation.LargeTest;
@@ -28,6 +25,10 @@ import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.model.Query;
import com.cyanogenmod.filemanager.util.CommandHelper;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* A class for testing find command.
*
@@ -36,8 +37,12 @@ import com.cyanogenmod.filemanager.util.CommandHelper;
public class FindCommandTest extends AbstractConsoleTest {
private static final String FIND_PATH =
- Environment.getDataDirectory().getAbsolutePath();
- private static final String FIND_TERM_PARTIAL = "shared"; //$NON-NLS-1$
+ Environment.getRootDirectory().getAbsolutePath();
+ private static final String FIND_TERM_PARTIAL = "build"; //$NON-NLS-1$
+
+ private static final File TEST_FILE =
+ new File (Environment.getRootDirectory(),
+ "build.prop"); //$NON-NLS-1$
/**
* @hide
@@ -73,21 +78,26 @@ public class FindCommandTest extends AbstractConsoleTest {
final List<FileSystemObject> files = new ArrayList<FileSystemObject>();
AsyncResultExecutable cmd =
CommandHelper.findFiles(getContext(), FIND_PATH, query, new AsyncResultListener() {
+ @Override
public void onAsyncStart() {
/**NON BLOCK**/
}
+ @Override
public void onAsyncEnd(boolean cancelled) {
synchronized (FindCommandTest.this.mSync) {
FindCommandTest.this.mNormalEnd = true;
FindCommandTest.this.mSync.notify();
}
}
+ @Override
public void onAsyncExitCode(int exitCode) {
/**NON BLOCK**/
}
+ @Override
public void onException(Exception cause) {
fail(String.valueOf(cause));
}
+ @Override
@SuppressWarnings("unchecked")
public void onPartialResult(Object results) {
FindCommandTest.this.mNewPartialData = true;
@@ -105,6 +115,16 @@ public class FindCommandTest extends AbstractConsoleTest {
assertTrue("no new partial data", this.mNewPartialData); //$NON-NLS-1$
assertNotNull("files==null", files); //$NON-NLS-1$
assertTrue("no objects returned", files.size() > 0); //$NON-NLS-1$
+ boolean found = false;
+ int cc = files.size();
+ for (int i = 0; i < cc; i++) {
+ FileSystemObject fso = files.get(i);
+ if (fso.getParent().compareTo(TEST_FILE.getParent()) == 0 &&
+ fso.getName().compareTo(TEST_FILE.getName()) == 0) {
+ found = true;
+ }
+ }
+ assertTrue(String.format("test file %s not found", TEST_FILE), found); //$NON-NLS-1$
}
}
diff --git a/tests/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommandTest.java b/tests/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommandTest.java
index 6a9b0ed7..fca1b04a 100644
--- a/tests/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommandTest.java
+++ b/tests/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommandTest.java
@@ -75,21 +75,26 @@ public class FolderUsageCommandTest extends AbstractConsoleTest {
this.mUsage = null;
AsyncResultExecutable cmd =
CommandHelper.getFolderUsage(getContext(), PATH, new AsyncResultListener() {
+ @Override
public void onAsyncStart() {
/**NON BLOCK**/
}
+ @Override
public void onAsyncEnd(boolean cancelled) {
synchronized (FolderUsageCommandTest.this.mSync) {
FolderUsageCommandTest.this.mNormalEnd = true;
FolderUsageCommandTest.this.mSync.notify();
}
}
+ @Override
public void onAsyncExitCode(int exitCode) {
/**NON BLOCK**/
}
+ @Override
public void onException(Exception cause) {
fail(String.valueOf(cause));
}
+ @Override
public void onPartialResult(Object result) {
FolderUsageCommandTest.this.mNewPartialData = true;
try {
diff --git a/tests/src/com/cyanogenmod/filemanager/commands/shell/ListCommandTest.java b/tests/src/com/cyanogenmod/filemanager/commands/shell/ListCommandTest.java
index 5fcc8bc1..7b3e5873 100644
--- a/tests/src/com/cyanogenmod/filemanager/commands/shell/ListCommandTest.java
+++ b/tests/src/com/cyanogenmod/filemanager/commands/shell/ListCommandTest.java
@@ -16,22 +16,18 @@
package com.cyanogenmod.filemanager.commands.shell;
-import java.util.List;
-
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
-import com.cyanogenmod.filemanager.model.BlockDevice;
-import com.cyanogenmod.filemanager.model.CharacterDevice;
import com.cyanogenmod.filemanager.model.Directory;
-import com.cyanogenmod.filemanager.model.DomainSocket;
import com.cyanogenmod.filemanager.model.FileSystemObject;
-import com.cyanogenmod.filemanager.model.NamedPipe;
import com.cyanogenmod.filemanager.model.RegularFile;
import com.cyanogenmod.filemanager.model.Symlink;
import com.cyanogenmod.filemanager.util.CommandHelper;
import com.cyanogenmod.filemanager.util.FileHelper;
+import java.util.List;
+
/**
* A class for testing list command.
*
@@ -90,21 +86,16 @@ public class ListCommandTest extends AbstractConsoleTest {
public void testParse() throws Exception {
ListCommand cmd = new ListCommand(LS_PATH, getConsole());
String in =
- "drwxr-xr-x root root 2012-05-04 01:51 acct\n" + //$NON-NLS-1$
- "-rw-r--r-- root root2 229 2012-05-04 01:51 boot.txt\n" + //$NON-NLS-1$
- "lrwxrwxrwx root root 2012-05-04 01:51 d -> " //$NON-NLS-1$
- + "/sys/kernel/debug\n" + //$NON-NLS-1$
- "prw-r--r-- root root 0 2012-05-04 01:51 pipe\n" + //$NON-NLS-1$
- "srw-r--r-- root root 0 2012-05-04 01:51 socket\n" + //$NON-NLS-1$
- "brw------- root root 7, 0 2012-05-04 01:51 loop0\n" + //$NON-NLS-1$
- "crw------- root root 4, 64 2012-05-04 01:51 ttyS0\n" + //$NON-NLS-1$
- "-rwsr-sr-t root root 229 2012-05-04 01:51 permission1\n" + //$NON-NLS-1$
- "-rwSr-Sr-T root root 229 2012-05-04 01:51 permission2"; //$NON-NLS-1$
+ "/acct 0 0 41ed 0 0 d 1054 3 0 0 1357390899 1357390899 1357390899 4096\n" + //$NON-NLS-1$
+ "/init.cm.rc 1238 8 81e8 0 0 1 370 1 0 0 1357390899 1357390899 1357390899 4096\n" + //$NON-NLS-1$
+ "/vendor 14 0 a1ff 0 0 1 1052 1 0 0 1357390899 1357390899 1357390899 4096\n" + //$NON-NLS-1$
+ "/cache 4096 8 41f9 1000 2001 b307 2 5 0 0 0 1357390900 1357390900 4096\n"; //$NON-NLS-1$
+
String err = ""; //$NON-NLS-1$
cmd.parse(in, err);
List<FileSystemObject> files = cmd.getResult();
assertNotNull("files==null", files); //$NON-NLS-1$
- assertTrue("length!=9", files.size() == 9); //$NON-NLS-1$
+ assertTrue("length!=4", files.size() == 4); //$NON-NLS-1$
assertTrue(
"files(0) is not a directory", //$NON-NLS-1$
files.get(0) instanceof Directory);
@@ -114,77 +105,22 @@ public class ListCommandTest extends AbstractConsoleTest {
assertTrue(
"files(2) is not a symlink", //$NON-NLS-1$
files.get(2) instanceof Symlink);
+ assertNotNull(
+ "files(2) linkref is null", //$NON-NLS-1$
+ ((Symlink)files.get(2)).getLinkRef());
assertTrue(
- "files(3) is not a named pipe", //$NON-NLS-1$
- files.get(3) instanceof NamedPipe);
- assertTrue(
- "files(4) is not a domain socket", //$NON-NLS-1$
- files.get(4) instanceof DomainSocket);
- assertTrue(
- "files(5) is not a block device", //$NON-NLS-1$
- files.get(5) instanceof BlockDevice);
- assertTrue(
- "files(6) is not a character device", //$NON-NLS-1$
- files.get(6) instanceof CharacterDevice);
- assertTrue(
- "files(0) != name", //$NON-NLS-1$
- files.get(0).getName().compareTo("acct") == 0); //$NON-NLS-1$
- assertTrue(
- "files(2) != name", //$NON-NLS-1$
- files.get(2).getName().compareTo("d") == 0); //$NON-NLS-1$
- assertTrue(
- "files(2) != link", //$NON-NLS-1$
- ((Symlink)files.get(2)).getLink().compareTo(
- "/sys/kernel/debug") == 0); //$NON-NLS-1$
- assertTrue(
- "files(1) != user", //$NON-NLS-1$
- files.get(1).getUser().getName().compareTo("root") == 0); //$NON-NLS-1$
+ "files(3) != user", //$NON-NLS-1$
+ files.get(3).getUser().getName().compareTo("system") == 0); //$NON-NLS-1$
assertTrue(
- "files(1) != group", //$NON-NLS-1$
- files.get(1).getGroup().getName().compareTo("root2") == 0); //$NON-NLS-1$
+ "files(3) != group", //$NON-NLS-1$
+ files.get(3).getGroup().getName().compareTo("cache") == 0); //$NON-NLS-1$
assertTrue(
"files(1) != size", //$NON-NLS-1$
- files.get(1).getSize() == 229);
+ files.get(1).getSize() == 1238);
assertTrue(
"files(1) != permissions", //$NON-NLS-1$
files.get(1).getPermissions()
- .toRawString().compareTo("rw-r--r--") == 0); //$NON-NLS-1$
- assertTrue(
- "files(7) != setuid", //$NON-NLS-1$
- files.get(7).getPermissions().getUser().isSetUID());
- assertTrue(
- "files(7) != setgid", //$NON-NLS-1$
- files.get(7).getPermissions().getGroup().isSetGID());
- assertTrue(
- "files(7) != stickybit", //$NON-NLS-1$
- files.get(7).getPermissions().getOthers().isStickybit());
- assertTrue(
- "files(7) != setuid+execute", //$NON-NLS-1$
- files.get(7).getPermissions().getUser().isExecute());
- assertTrue(
- "files(7) != setgid+execute", //$NON-NLS-1$
- files.get(7).getPermissions().getGroup().isExecute());
- assertTrue(
- "files(7) != stickybit+execute", //$NON-NLS-1$
- files.get(7).getPermissions().getOthers().isExecute());
- assertTrue(
- "files(8) != setuid", //$NON-NLS-1$
- files.get(8).getPermissions().getUser().isSetUID());
- assertTrue(
- "files(8) != setgid", //$NON-NLS-1$
- files.get(8).getPermissions().getGroup().isSetGID());
- assertTrue(
- "files(8) != stickybit", //$NON-NLS-1$
- files.get(8).getPermissions().getOthers().isStickybit());
- assertTrue(
- "files(8) != setuid+execute", //$NON-NLS-1$
- !files.get(8).getPermissions().getUser().isExecute());
- assertTrue(
- "files(8) != setgid+execute", //$NON-NLS-1$
- !files.get(8).getPermissions().getGroup().isExecute());
- assertTrue(
- "files(8) != stickybit+execute", //$NON-NLS-1$
- !files.get(8).getPermissions().getOthers().isExecute());
+ .toRawString().compareTo("rwxr-x---") == 0); //$NON-NLS-1$
}
}
diff --git a/tests/src/com/cyanogenmod/filemanager/commands/shell/ReadCommandTest.java b/tests/src/com/cyanogenmod/filemanager/commands/shell/ReadCommandTest.java
index b0625dbd..51cb8a5a 100644
--- a/tests/src/com/cyanogenmod/filemanager/commands/shell/ReadCommandTest.java
+++ b/tests/src/com/cyanogenmod/filemanager/commands/shell/ReadCommandTest.java
@@ -68,21 +68,26 @@ public class ReadCommandTest extends AbstractConsoleTest {
final StringBuffer sb = new StringBuffer();
AsyncResultExecutable cmd =
CommandHelper.read(getContext(), READ_FILE, new AsyncResultListener() {
+ @Override
public void onAsyncStart() {
/**NON BLOCK**/
}
+ @Override
public void onAsyncEnd(boolean cancelled) {
synchronized (ReadCommandTest.this.mSync) {
ReadCommandTest.this.mNormalEnd = true;
ReadCommandTest.this.mSync.notify();
}
}
+ @Override
public void onAsyncExitCode(int exitCode) {
/**NON BLOCK**/
}
+ @Override
public void onException(Exception cause) {
fail(String.valueOf(cause));
}
+ @Override
public void onPartialResult(Object results) {
ReadCommandTest.this.mNewPartialData = true;
sb.append(new String((byte[])results));
diff --git a/tests/src/com/cyanogenmod/filemanager/commands/shell/UncompressCommandTest.java b/tests/src/com/cyanogenmod/filemanager/commands/shell/UncompressCommandTest.java
index 6fbfb3aa..59c4041c 100644
--- a/tests/src/com/cyanogenmod/filemanager/commands/shell/UncompressCommandTest.java
+++ b/tests/src/com/cyanogenmod/filemanager/commands/shell/UncompressCommandTest.java
@@ -184,21 +184,26 @@ public class UncompressCommandTest extends AbstractConsoleTest {
cmd =
CommandHelper.uncompress(
getContext(), src, null, new AsyncResultListener() {
+ @Override
public void onAsyncStart() {
/**NON BLOCK**/
}
+ @Override
public void onAsyncEnd(boolean cancelled) {
synchronized (UncompressCommandTest.this.mSync) {
UncompressCommandTest.this.mNormalEnd = true;
UncompressCommandTest.this.mSync.notify();
}
}
+ @Override
public void onAsyncExitCode(int exitCode) {
/**NON BLOCK**/
}
+ @Override
public void onException(Exception cause) {
fail(String.valueOf(cause));
}
+ @Override
public void onPartialResult(Object result) {
UncompressCommandTest.this.mNewPartialData = true;
Log.d(TAG, (String)result);
diff --git a/tests/src/com/cyanogenmod/filemanager/commands/shell/WriteCommandTest.java b/tests/src/com/cyanogenmod/filemanager/commands/shell/WriteCommandTest.java
index 2e14a993..ec04ab10 100644
--- a/tests/src/com/cyanogenmod/filemanager/commands/shell/WriteCommandTest.java
+++ b/tests/src/com/cyanogenmod/filemanager/commands/shell/WriteCommandTest.java
@@ -16,9 +16,6 @@
package com.cyanogenmod.filemanager.commands.shell;
-import java.io.OutputStream;
-import java.util.Random;
-
import android.os.Environment;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
@@ -27,6 +24,9 @@ import com.cyanogenmod.filemanager.commands.AsyncResultListener;
import com.cyanogenmod.filemanager.commands.WriteExecutable;
import com.cyanogenmod.filemanager.util.CommandHelper;
+import java.io.OutputStream;
+import java.util.Random;
+
/**
* A class for testing write command.
*
@@ -61,12 +61,17 @@ public class WriteCommandTest extends AbstractConsoleTest {
WriteExecutable cmd =
CommandHelper.write(getContext(),
WRITE_FILE_SMALL, new AsyncResultListener() {
+ @Override
public void onAsyncStart() {/**NON BLOCK**/}
+ @Override
public void onAsyncEnd(boolean cancelled) {/**NON BLOCK**/}
+ @Override
public void onAsyncExitCode(int exitCode) {/**NON BLOCK**/}
+ @Override
public void onException(Exception cause) {
fail(String.valueOf(cause));
}
+ @Override
public void onPartialResult(Object results) {/**NON BLOCK**/}
}, getConsole());
OutputStream os = cmd.createOutputStream();
@@ -93,12 +98,17 @@ public class WriteCommandTest extends AbstractConsoleTest {
WriteExecutable cmd =
CommandHelper.write(getContext(),
WRITE_FILE_LARGE, new AsyncResultListener() {
+ @Override
public void onAsyncStart() {/**NON BLOCK**/}
+ @Override
public void onAsyncEnd(boolean cancelled) {/**NON BLOCK**/}
+ @Override
public void onAsyncExitCode(int exitCode) {/**NON BLOCK**/}
+ @Override
public void onException(Exception cause) {
fail(String.valueOf(cause));
}
+ @Override
public void onPartialResult(Object results) {/**NON BLOCK**/}
}, getConsole());
OutputStream os = cmd.createOutputStream();
diff --git a/themes/res/values/arrays.xml b/themes/res/values/arrays.xml
index dc6d8fee..ec6409b1 100644
--- a/themes/res/values/arrays.xml
+++ b/themes/res/values/arrays.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The identifiers of the themes that this app contains. All the resources
of every theme MUST be qualified with the identifier of the theme -->