diff options
author | Richard MacGregor <rmacgregor@cyngn.com> | 2015-07-09 17:16:51 -0700 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2016-11-02 18:36:38 -0700 |
commit | 6c7b68ad01d067f75d5dc4d2b3a67a373b59a52e (patch) | |
tree | dfa7357d3e82c349aab61d8809dc0506347fc695 | |
parent | 22496a9cd0e0efbeac228c1ca40d1e681a800611 (diff) | |
download | android_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
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; + } + } + } } |