aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard MacGregor <rmacgregor@cyngn.com>2015-07-09 17:16:51 -0700
committerSteve Kondik <steve@cyngn.com>2016-11-02 18:36:38 -0700
commit6c7b68ad01d067f75d5dc4d2b3a67a373b59a52e (patch)
treedfa7357d3e82c349aab61d8809dc0506347fc695
parent22496a9cd0e0efbeac228c1ca40d1e681a800611 (diff)
downloadandroid_packages_apps_CMFileManager-6c7b68ad01d067f75d5dc4d2b3a67a373b59a52e.tar.gz
android_packages_apps_CMFileManager-6c7b68ad01d067f75d5dc4d2b3a67a373b59a52e.tar.bz2
android_packages_apps_CMFileManager-6c7b68ad01d067f75d5dc4d2b3a67a373b59a52e.zip
Add roots list to picker activity
When browsing via picker activity, the roots list needs to be shown. To do this, add a new "parent" to each root head directory which points to the roots directory. Change-Id: I1a8d270ea000777756893ab4a44c03740a76f3dc
-rw-r--r--res/layout/navigation_view_simple.xml8
-rw-r--r--res/layout/picker.xml3
-rw-r--r--src/com/cyanogenmod/filemanager/activities/PickerActivity.java14
-rw-r--r--src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java1
-rw-r--r--src/com/cyanogenmod/filemanager/model/RootDirectory.java50
-rwxr-xr-xsrc/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java62
-rw-r--r--src/com/cyanogenmod/filemanager/util/FileHelper.java6
-rw-r--r--src/com/cyanogenmod/filemanager/util/StorageHelper.java144
8 files changed, 265 insertions, 23 deletions
diff --git a/res/layout/navigation_view_simple.xml b/res/layout/navigation_view_simple.xml
index 4ac05c89..ede44398 100644
--- a/res/layout/navigation_view_simple.xml
+++ b/res/layout/navigation_view_simple.xml
@@ -15,7 +15,7 @@
-->
<com.cyanogenmod.filemanager.ui.widgets.FlingerListView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/navigation_view_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/navigation_view_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
diff --git a/res/layout/picker.xml b/res/layout/picker.xml
index f9ce1b7e..65a21acc 100644
--- a/res/layout/picker.xml
+++ b/res/layout/picker.xml
@@ -28,7 +28,8 @@
android:layout_width="match_parent"
android:layout_height="@dimen/default_row_height"
android:layout_marginStart="@dimen/extra_large_margin"
- android:layout_marginEnd="@dimen/extra_large_margin"/>
+ android:layout_marginEnd="@dimen/extra_large_margin"
+ android:visibility="gone"/>
<include layout="@layout/vertical_divider" />
diff --git a/src/com/cyanogenmod/filemanager/activities/PickerActivity.java b/src/com/cyanogenmod/filemanager/activities/PickerActivity.java
index ba7f3ff8..0316f5de 100644
--- a/src/com/cyanogenmod/filemanager/activities/PickerActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/PickerActivity.java
@@ -416,7 +416,7 @@ public class PickerActivity extends Activity
if (initialDir != null) {
rootDirectory = initialDir.getAbsolutePath();
} else {
- rootDirectory = FileHelper.ROOT_DIRECTORY;
+ rootDirectory = FileHelper.ROOTS_LIST;
}
this.mHandler = new Handler();
@@ -656,7 +656,19 @@ public class PickerActivity extends Activity
*/
@Override
public void onDirectoryChanged(FileSystemObject item) {
+ int visibility = View.VISIBLE;
this.mCurrentDirectory = item;
+ if (TextUtils.equals(mCurrentDirectory.getName(), FileHelper.ROOTS_LIST)
+ && mCurrentDirectory.getParent() == null) {
+ mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
+ visibility = View.GONE;
+ } else {
+ mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
+ }
+ View breadView = mRootView.findViewById(R.id.breadcrumb_view);
+ if (breadView != null && breadView.getVisibility() != visibility) {
+ breadView.setVisibility(visibility);
+ }
}
/**
diff --git a/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java b/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java
index 1dd9ca77..028a542a 100644
--- a/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java
+++ b/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java
@@ -37,6 +37,7 @@ import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.model.ParentDirectory;
+import com.cyanogenmod.filemanager.model.RootDirectory;
import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
import com.cyanogenmod.filemanager.preferences.Preferences;
import com.cyanogenmod.filemanager.ui.IconHolder;
diff --git a/src/com/cyanogenmod/filemanager/model/RootDirectory.java b/src/com/cyanogenmod/filemanager/model/RootDirectory.java
new file mode 100644
index 00000000..168976a0
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/model/RootDirectory.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.
+ */
+
+package com.cyanogenmod.filemanager.model;
+
+/**
+ * A class that represents a directory.
+ */
+public class RootDirectory extends FileSystemObject {
+ private String mRootPath;
+
+ /**
+ * Constructor of <code>FileSystemObject</code>.
+ *
+ * @param name The name of the object
+ * @param summary The summary for the root directory
+ * @param path The root path for this object
+ * @param icon The root's icon
+ * @param primaryColor The roots primary color
+ */
+ public RootDirectory(String name, String summary, String path, int icon, int primaryColor) {
+ super(name, null, null, null, null, 0L, null, null, null);
+ mRootPath = path;
+ if (icon != -1) {
+ setResourceIconId(icon);
+ }
+ }
+
+ @Override
+ public char getUnixIdentifier() {
+ return 0;
+ }
+
+ public String getRootPath() {
+ return mRootPath;
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
index 1ffc4910..8df7623b 100755
--- a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
+++ b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
@@ -49,6 +49,7 @@ import com.cyanogenmod.filemanager.listeners.OnSelectionListener;
import com.cyanogenmod.filemanager.model.Directory;
import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.model.ParentDirectory;
+import com.cyanogenmod.filemanager.model.RootDirectory;
import com.cyanogenmod.filemanager.model.Symlink;
import com.cyanogenmod.filemanager.parcelables.NavigationViewInfoParcelable;
import com.cyanogenmod.filemanager.parcelables.SearchInfoParcelable;
@@ -256,9 +257,15 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
*/
@Override
protected List<FileSystemObject> doInBackground(String... params) {
- // Check navigation security (don't allow to go outside the ChRooted environment if one
- // is created)
- mNewDirChecked = checkChRootedNavigation(params[0]);
+
+ if (TextUtils.equals(params[0], FileHelper.ROOTS_LIST)) {
+ // If new directory is "Roots list" don't check ChRooted evnironment
+ mNewDirChecked = params[0];
+ } else {
+ // Check navigation security (don't allow to go outside the ChRooted environment if one
+ // is created)
+ mNewDirChecked = checkChRootedNavigation(params[0]);
+ }
mHasChanged = !(NavigationView.this.mPreviousDir != null &&
NavigationView.this.mPreviousDir.compareTo(mNewDirChecked) == 0);
@@ -289,12 +296,17 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
}
}
- //Get the files, resolve links and apply configuration
- //(sort, hidden, ...)
- List<FileSystemObject> files = NavigationView.this.mFiles;
- if (!mUseCurrent) {
- files = CommandHelper.listFiles(getContext(), mNewDirChecked, null);
- mNewDirFSO = CommandHelper.getFileInfo(getContext(), mNewDirChecked, null);
+ List<FileSystemObject> files = null;
+ if (TextUtils.equals(mNewDirChecked, FileHelper.ROOTS_LIST)) {
+ files = StorageHelper.getStorageVolumesFileSystemObjectList(getContext());
+ } else {
+ //Get the files, resolve links and apply configuration
+ //(sort, hidden, ...)
+ files = NavigationView.this.mFiles;
+ if (!mUseCurrent) {
+ files = CommandHelper.listFiles(getContext(), mNewDirChecked, null);
+ mNewDirFSO = CommandHelper.getFileInfo(getContext(), mNewDirChecked, null);
+ }
}
//Apply user preferences
@@ -599,13 +611,7 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
this.mFiles = new ArrayList<FileSystemObject>();
// Is ChRooted environment?
- if (this.mNavigationMode.compareTo(NAVIGATION_MODE.PICKABLE) == 0) {
- // Pick mode is always ChRooted
- this.mChRooted = true;
- } else {
- this.mChRooted =
- FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) == 0;
- }
+ this.mChRooted = FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) == 0;
//Retrieve the default configuration
if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
@@ -1153,11 +1159,29 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
return;
}
+ List<FileSystemObject> sortedFiles = null;
+ if (!TextUtils.equals(FileHelper.ROOTS_LIST, newDir)) {
+ //Apply user preferences
+ sortedFiles =
+ FileHelper.applyUserPreferences(files, this.mRestrictions, this.mChRooted);
+ } else {
+ sortedFiles = files;
+ }
+
//Remove parent directory if we are in the root of a chrooted environment
- if (this.mChRooted && StorageHelper.isStorageVolume(newDir)) {
+ if (this.mChRooted && StorageHelper.isStorageVolume(newDir) ||
+ TextUtils.equals(newDir, FileHelper.ROOT_DIRECTORY)) {
if (files.size() > 0 && files.get(0) instanceof ParentDirectory) {
files.remove(0);
}
+ if (mNavigationMode.compareTo(NAVIGATION_MODE.PICKABLE) == 0) {
+ files.add(0, new ParentDirectory(FileHelper.ROOTS_LIST));
+ }
+ } else if (!TextUtils.equals(FileHelper.ROOTS_LIST, newDir) &&
+ files.size() > 0 && !(files.get(0) instanceof ParentDirectory)) {
+ if (mNavigationMode.compareTo(NAVIGATION_MODE.PICKABLE) == 0) {
+ files.add(0, new ParentDirectory(FileHelper.ROOTS_LIST));
+ }
}
//Add to history?
@@ -1305,6 +1329,10 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
// Open the link ref
fso = symlink.getLinkRef();
+ } else if (fso instanceof RootDirectory) {
+ RootDirectory rootDirectory = (RootDirectory)fso;
+ changeCurrentDir(rootDirectory.getRootPath(), true);
+ return;
}
// Open the file (edit or pick)
diff --git a/src/com/cyanogenmod/filemanager/util/FileHelper.java b/src/com/cyanogenmod/filemanager/util/FileHelper.java
index c1adccb0..926c85a6 100644
--- a/src/com/cyanogenmod/filemanager/util/FileHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/FileHelper.java
@@ -103,6 +103,12 @@ public final class FileHelper {
* The root directory.
* @hide
*/
+ public static final String ROOTS_LIST = "ROOTS_LIST"; //$NON-NLS-1$
+
+ /**
+ * The root directory.
+ * @hide
+ */
public static final String ROOT_DIRECTORY = "/"; //$NON-NLS-1$
/**
diff --git a/src/com/cyanogenmod/filemanager/util/StorageHelper.java b/src/com/cyanogenmod/filemanager/util/StorageHelper.java
index 32dcba95..31e51e3d 100644
--- a/src/com/cyanogenmod/filemanager/util/StorageHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/StorageHelper.java
@@ -16,28 +16,42 @@
package com.cyanogenmod.filemanager.util;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.TextUtils;
+import android.util.Log;
import com.cyanogenmod.filemanager.FileManagerApplication;
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.console.VirtualMountPointConsole;
+import com.cyanogenmod.filemanager.model.Bookmark;
+import com.cyanogenmod.filemanager.model.Bookmark.BOOKMARK_TYPE;
import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.model.MountPoint;
+import com.cyanogenmod.filemanager.model.NavigationDrawerItem.NavigationDrawerItemType;
+import com.cyanogenmod.filemanager.model.RootDirectory;
+import com.cyanogenmod.filemanager.preferences.AccessMode;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import static com.cyanogenmod.filemanager.model.Bookmark.BOOKMARK_TYPE.SDCARD;
+import static com.cyanogenmod.filemanager.model.Bookmark.BOOKMARK_TYPE.USB;
+
/**
* A helper class with useful methods for deal with storages.
*/
public final class StorageHelper {
+ private static final String TAG = StorageHelper.class.getSimpleName();
+ private static boolean DEBUG = false;
private static final String STR_USB = "usb"; // $NON-NLS-1$
+
private static StorageVolume[] sStorageVolumes;
/**
@@ -312,4 +326,134 @@ public final class StorageHelper {
}
return path;
}
+
+ /**
+ * Returns the list of mounted volumes (local, sdcard, usb, storage providers, protected)
+ * NOTE: This is blocking and should be called asynchronously...
+ *
+ * @return files List of FileSystemObject representing each mounted volume
+ */
+ public static List<FileSystemObject> getStorageVolumesFileSystemObjectList(Context ctx) {
+ List<FileSystemObject> files = loadStorageVolumeList(ctx);
+ return files;
+ }
+
+ private static List<FileSystemObject> loadStorageVolumeList(Context ctx) {
+ List<FileSystemObject> storageVolumesList = new ArrayList<FileSystemObject>();
+
+ String title = null;
+ String summary = null;
+ int color;
+
+ // Determine display mode
+ boolean showRoot = FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) != 0;
+ NavigationDrawerItemType itemType = showRoot ?
+ NavigationDrawerItemType.DOUBLE : NavigationDrawerItemType.SINGLE;
+
+ // Load Local Storage
+ title = ctx.getResources().getString(R.string.navigation_item_title_local);
+ summary = StorageHelper.getLocalStoragePath(ctx);
+ color = ctx.getResources().getColor(R.color.default_primary);
+ storageVolumesList.add(new RootDirectory(title, summary, summary,
+ R.drawable.ic_source_internal, color));
+
+ // Show/hide root
+ if (showRoot) {
+ title = ctx.getString(R.string.navigation_item_title_root);
+ summary = FileHelper.ROOT_DIRECTORY;
+ color = ctx.getResources().getColor(R.color.root_primary);
+ storageVolumesList.add(new RootDirectory(title, summary, summary,
+ R.drawable.ic_source_root_d, color));
+ }
+
+ loadExternalStorageItems(ctx, storageVolumesList, itemType);
+
+ loadSecureStorage(ctx, storageVolumesList);
+
+ return storageVolumesList;
+ }
+
+ /**
+ * Method that loads the secure digital card and usb storage menu items from the system.
+ */
+ private static void loadExternalStorageItems(Context ctx,
+ List<FileSystemObject> storageVolumesList, NavigationDrawerItemType itemType) {
+ List<Bookmark> sdBookmarks = new ArrayList<Bookmark>();
+ List<Bookmark> usbBookmarks = new ArrayList<Bookmark>();
+
+ try {
+ // Recovery sdcards and usb from storage manager
+ StorageVolume[] volumes =
+ StorageHelper.getStorageVolumes(ctx, true);
+ for (StorageVolume volume: volumes) {
+ if (volume != null) {
+ String mountedState = volume.getState();
+ String path = volume.getPath();
+ if (!Environment.MEDIA_MOUNTED.equalsIgnoreCase(mountedState) &&
+ !Environment.MEDIA_MOUNTED_READ_ONLY.equalsIgnoreCase(mountedState)) {
+ if (DEBUG) {
+ Log.w(TAG, "Ignoring '" + path + "' with state of '"
+ + mountedState + "'");
+ }
+ continue;
+ }
+ if (!TextUtils.isEmpty(path)) {
+ String lowerPath = path.toLowerCase(Locale.ROOT);
+ if (lowerPath.contains(STR_USB)) {
+ usbBookmarks.add(new Bookmark(USB, StorageHelper
+ .getStorageVolumeDescription(ctx,
+ volume), path));
+ } else {
+ sdBookmarks.add(new Bookmark(SDCARD, StorageHelper
+ .getStorageVolumeDescription(ctx,
+ volume), path));
+ }
+ }
+ }
+ }
+
+ String localStorage = ctx.getString(R.string.local_storage_path);
+
+ // Load the bookmarks
+ for (Bookmark b : sdBookmarks) {
+ if (TextUtils.equals(b.getPath(), localStorage)) continue;
+ int hash = b.hashCode();
+ int color = ctx.getResources().getColor(R.color.sdcard_primary);
+ storageVolumesList.add(new RootDirectory(b.getName(), b.getPath(), b.getPath(),
+ R.drawable.ic_source_sd_card, color));
+ }
+ for (Bookmark b : usbBookmarks) {
+ int hash = b.hashCode();
+ int color = ctx.getResources().getColor(R.color.usb_primary);
+ storageVolumesList.add(new RootDirectory(b.getName(), b.getPath(), b.getPath(),
+ R.drawable.ic_source_usb, color));
+ }
+ }
+ catch (Throwable ex) {
+ Log.e(TAG, "Load filesystem bookmarks failed", ex); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Method that loads the secure storage mount point.
+ */
+ private static void loadSecureStorage(Context ctx, List<FileSystemObject> storageVolumesList) {
+ List<MountPoint> mps = VirtualMountPointConsole.getVirtualMountPoints();
+ for (MountPoint mp : mps) {
+ BOOKMARK_TYPE type = null;
+ String name = null;
+ if (mp.isSecure()) {
+ type = BOOKMARK_TYPE.SECURE;
+ name = ctx.getString(R.string.navigation_item_title_protected);
+ Bookmark b = new Bookmark(type, name, mp.getMountPoint());
+
+ int color = ctx.getResources().getColor(R.color.protected_primary);
+ storageVolumesList.add(new RootDirectory(b.getName(), b.getPath(), b.getPath(),
+ R.drawable.ic_source_protected, color));
+ break;
+ } else {
+ continue;
+ }
+ }
+ }
}