aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 -->