Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f0bce4d authored by Richard MacGregor's avatar Richard MacGregor
Browse files

Fix drawer some drawer mount points

Add drawer mount points for:
Local Storage
Root (only in privilaged mode)
SDCard (if available)
USB (if available)
StorageAPI

Still needs to be done:
Secure Storage mount point

Change-Id: Idec79d78ab7080897ccbb440aa2ed6bf1cae9bda
parent 62790e96
Loading
Loading
Loading
Loading
+9 −18
Original line number Diff line number Diff line
@@ -22,35 +22,26 @@
        android:id="@+id/navigation_group_home">
        <item android:id="@+id/navigation_item_home"
            android:icon="@drawable/ic_home"
            android:title="Home"
            android:checked="true" />
            android:title="@string/navigation_item_title_home" />
        <item android:id="@+id/navigation_item_favorites"
            android:icon="@drawable/ic_favorite_on"
            android:title="Favorites"
            android:title="@string/navigation_item_title_favorites"
            android:visible="false" /> <!-- hidden until wired up -->
    </group>

    <group
        android:checkableBehavior="none"
        android:id="@+id/navigation_group_roots">
        <!-- TODO: Replace with dynamically created roots -->
        <item android:id="@+id/navigation_item_internal"
            android:icon="@drawable/ic_source_internal"
            android:title="Local storage" />
            android:title="@string/navigation_item_title_local" />
        <item android:id="@+id/navigation_item_root_d"
            android:icon="@drawable/ic_source_root_d"
            android:title="Root directory"
            android:visible="false" /> <!-- hidden until wired up -->
        <item android:id="@+id/navigation_item_sd_card"
            android:icon="@drawable/ic_source_sd_card"
            android:title="SD card"
            android:visible="false" /> <!-- hidden until wired up -->
        <item android:id="@+id/navigation_item_usb"
            android:icon="@drawable/ic_source_usb"
            android:title="USB storage"
            android:visible="false" /> <!-- hidden until wired up -->
            android:title="@string/navigation_item_title_root"
            android:visible="false" />
        <item android:id="@+id/navigation_item_protected"
            android:icon="@drawable/ic_source_protected"
            android:title="Protected storage"
            android:title="@string/navigation_item_title_protected"
            android:orderInCategory="@integer/navigation_item_order_after_roots"
            android:visible="false" /> <!-- hidden until wired up -->
    </group>
@@ -60,12 +51,12 @@
        android:id="@+id/navigation_group_settings">
        <item android:id="@+id/navigation_item_manage"
            android:icon="@drawable/ic_storage_sources"
            android:title="Manage storage sources"
            android:title="@string/navigation_item_title_manage"
            android:orderInCategory="@integer/navigation_item_order_after_roots"
            android:visible="false" /> <!-- hidden until wired up -->
        <item android:id="@+id/navigation_item_settings"
            android:icon="@drawable/ic_settings"
            android:title="Settings"
            android:title="@string/navigation_item_title_settings"
            android:orderInCategory="@integer/navigation_item_order_after_roots" />
    </group>
</menu>
+3 −0
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@
    <!-- The virtual storage directory (virtual filesystem are listed here) -->
    <string name="virtual_storage_dir" translatable="false">/storage</string>

    <!-- The internal (local) storage directory -->
    <string name="local_storage_path" translatable="false">/storage/emulated/0</string>

    <!-- The shell commands used by this application. All of this commands should
         exist to allow the use of a shell console (and access to root). If any
         of this commands are not present in the system, then app will start in
+15 −0
Original line number Diff line number Diff line
@@ -385,6 +385,21 @@
    <!-- Bookmarks - Bookmarks - Actions - Bookmark successfully added -->
    <string name="bookmarks_msgs_add_success">The bookmark was added successfully.</string>

    <!-- Navigation Drawer Item Titles - Home -->
    <string name="navigation_item_title_home">Home</string>
    <!-- Navigation Drawer Item Titles - Favorites -->
    <string name="navigation_item_title_favorites">Favorites</string>
    <!-- Navigation Drawer Item Titles - Local storage -->
    <string name="navigation_item_title_local">Local storage</string>
    <!-- Navigation Drawer Item Titles - Root directory -->
    <string name="navigation_item_title_root">Root directory</string>
    <!-- Navigation Drawer Item Titles - protected -->
    <string name="navigation_item_title_protected">Protected storage</string>
    <!-- Navigation Drawer Item Titles - Manage storage sources -->
    <string name="navigation_item_title_manage">Manage storage sources</string>
    <!-- Navigation Drawer Item Titles - Settings -->
    <string name="navigation_item_title_settings">Settings</string>

    <!-- Initial directory dialog title -->
    <string name="initial_directory_dialog_title">Initial folder</string>
    <!-- Initial directory label -->
+45 −83
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ import android.app.Activity;
import android.app.Dialog;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.os.Bundle;
@@ -30,19 +28,16 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
import com.cyanogenmod.filemanager.FileManagerApplication;

import com.cyanogen.ambient.common.api.PendingResult;
import com.cyanogen.ambient.common.api.ResultCallback;
import com.cyanogen.ambient.storage.StorageApi;
import com.cyanogen.ambient.storage.provider.StorageProviderInfo;
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.activities.preferences.SettingsPreferences;
import com.cyanogenmod.filemanager.console.ConsoleHolder;
import com.cyanogenmod.filemanager.console.storageapi.StorageApiConsole;
import com.cyanogenmod.filemanager.controllers.NavigationDrawerController;
import com.cyanogenmod.filemanager.model.Bookmark;
import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
@@ -51,13 +46,13 @@ import com.cyanogenmod.filemanager.ui.fragments.HomeFragment;
import com.cyanogenmod.filemanager.ui.fragments.NavigationFragment;
import com.cyanogenmod.filemanager.util.FileHelper;
import com.cyanogenmod.filemanager.util.MimeTypeHelper.MimeTypeCategory;
import com.cyanogenmod.filemanager.util.StorageHelper;

import java.io.File;
import java.io.InvalidClassException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * The main navigation activity. This activity is the center of the application.
@@ -72,8 +67,7 @@ import java.util.Map;
 * the app is killed, is restarted from his initial state.
 */
public class MainActivity extends ActionBarActivity
        implements NavigationView.OnNavigationItemSelectedListener,
        ResultCallback<StorageProviderInfo.ProviderInfoListResult> {
        implements NavigationView.OnNavigationItemSelectedListener {

    private static final String TAG = MainActivity.class.getSimpleName();

@@ -127,22 +121,9 @@ public class MainActivity extends ActionBarActivity

    static String MIME_TYPE_LOCALIZED_NAMES[];

    int[][] color_states = new int[][] {
            new int[] {android.R.attr.state_checked}, // checked
            new int[0] // default
    };

    // TODO: Replace with legitimate colors per item.
    int[] colors = new int[] {
            R.color.favorites_primary,
            Color.BLACK
    };

    private Toolbar mToolbar;
    private Fragment currentFragment;
    private DrawerLayout mDrawerLayout;
    private NavigationView mNavigationDrawer;
    private Map<Integer, StorageProviderInfo> mProvidersMap;
    private NavigationDrawerController mNavigationDrawerController;

    /**
     * {@inheritDoc}
@@ -155,27 +136,15 @@ public class MainActivity extends ActionBarActivity
        setContentView(R.layout.navigation);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mNavigationDrawer = (NavigationView) findViewById(R.id.navigation_view);
        mNavigationDrawer.setNavigationItemSelectedListener(this);
        ColorStateList colorStateList = new ColorStateList(color_states, colors);
        // TODO: Figure out why the following doesn't work correctly...
        mNavigationDrawer.setItemTextColor(colorStateList);
        mNavigationDrawer.setItemIconTintList(colorStateList);
        NavigationView navigationDrawer = (NavigationView) findViewById(R.id.navigation_view);
        navigationDrawer.setNavigationItemSelectedListener(this);
        mNavigationDrawerController = new NavigationDrawerController(this, navigationDrawer);
        mNavigationDrawerController.loadNavigationDrawerItems();

        MIME_TYPE_LOCALIZED_NAMES = MimeTypeCategory.getFriendlyLocalizedNames(this);

        showWelcomeMsg();

        /*
         * TEST CODE
         * TODO: MOVE SOMEWHERE MORE LEGITIMATE
         */
        mProvidersMap = new HashMap<Integer, StorageProviderInfo>();
        StorageApi storageApi = StorageApi.getInstance();
        PendingResult<StorageProviderInfo.ProviderInfoListResult> pendingResult =
                storageApi.fetchProviders(this);
        pendingResult.setResultCallback(this);

        setCurrentFragment(FragmentType.HOME);

        //Initialize nfc adapter
@@ -250,11 +219,11 @@ public class MainActivity extends ActionBarActivity
     */
    @Override
    public boolean onNavigationItemSelected(MenuItem menuItem) {
        menuItem.setChecked(false);
        int id = menuItem.getItemId();
        switch (id) {
            case R.id.navigation_item_home:
                if (DEBUG) Log.d(TAG, "onNavigationItemSelected::navigation_item_home");
                getIntent().putExtra(EXTRA_NAVIGATE_TO, FileHelper.ROOT_DIRECTORY);
                setCurrentFragment(FragmentType.HOME);
                break;
            case R.id.navigation_item_favorites:
@@ -263,20 +232,13 @@ public class MainActivity extends ActionBarActivity
                break;
            case R.id.navigation_item_internal:
                if (DEBUG) Log.d(TAG, "onNavigationItemSelected::navigation_item_favorites");
                getIntent().putExtra(EXTRA_NAVIGATE_TO, FileHelper.ROOT_DIRECTORY);
                getIntent().putExtra(EXTRA_NAVIGATE_TO, StorageHelper.getLocalStoragePath(this));
                setCurrentFragment(FragmentType.NAVIGATION);
                break;
            case R.id.navigation_item_root_d:
                // TODO: Implement this path
                if (DEBUG) Log.d(TAG, "onNavigationItemSelected::navigation_item_root_d");
                break;
            case R.id.navigation_item_sd_card:
                // TODO: Implement this path
                if (DEBUG) Log.d(TAG, "onNavigationItemSelected::navigation_item_sd_card");
                break;
            case R.id.navigation_item_usb:
                // TODO: Implement this path
                if (DEBUG) Log.d(TAG, "onNavigationItemSelected::navigation_item_usb");
                getIntent().putExtra(EXTRA_NAVIGATE_TO, FileHelper.ROOT_DIRECTORY);
                setCurrentFragment(FragmentType.NAVIGATION);
                break;
            case R.id.navigation_item_protected:
                // TODO: Implement this path
@@ -292,47 +254,47 @@ public class MainActivity extends ActionBarActivity
                break;
            default:
                if (DEBUG) Log.d(TAG, String.format("onNavigationItemSelected::default (%d)", id));
                String path = null;
                // Check for item id in storage bookmarks
                Bookmark bookmark = mNavigationDrawerController.getBookmarkFromMenuItem(id);
                if (bookmark != null) {
                    path = bookmark.getPath();
                } else {
                    // Check for item id in remote roots
                StorageProviderInfo providerInfo = mProvidersMap.get(id);
                getIntent().putExtra(EXTRA_NAVIGATE_TO,
                        StorageApiConsole.constructStorageApiFilePathFromProvider(
                    StorageProviderInfo providerInfo =
                            mNavigationDrawerController.getProviderInfoFromMenuItem(id);

                    if (providerInfo != null) {
                        path = StorageApiConsole.constructStorageApiFilePathFromProvider(
                                providerInfo.getRootDocumentId(),
                                StorageApiConsole.getHashCodeFromProvider(providerInfo)));
                                StorageApiConsole.getHashCodeFromProvider(providerInfo));
                    }
                }

                if (!TextUtils.isEmpty(path)) {
                    // Check for item id in remote roots
                    getIntent().putExtra(EXTRA_NAVIGATE_TO, path);
                    setCurrentFragment(FragmentType.NAVIGATION);
                } else {
                    return false;
                }
                break;
        }
        mDrawerLayout.closeDrawers();
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onResult(StorageProviderInfo.ProviderInfoListResult providerInfoListResult) {
        List<StorageProviderInfo> providerInfoList =
                providerInfoListResult.getProviderInfoList();
        if (providerInfoList == null) {
            Log.e(TAG, "no results returned");
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == INTENT_REQUEST_SETTINGS) {
            // reset bookmarks list to default as the user could changed the
            // root mode which changes the system bookmarks
            mNavigationDrawerController.loadNavigationDrawerItems();
            return;
        }
        if (DEBUG) Log.v(TAG, "got result(s)! " + providerInfoList.size());
        for (StorageProviderInfo providerInfo : providerInfoList) {
            StorageApi sapi = StorageApi.getInstance();

            // Add provider to map
            int providerHashCode = StorageApiConsole.getHashCodeFromProvider(providerInfo);
            mProvidersMap.put(providerHashCode, providerInfo);

            // Verify console exists, or create one
            StorageApiConsole.registerStorageApiConsole(this, sapi, providerInfo);

            // Concatenate title and summary
            // TODO: Change to two line menu items
            String title = providerInfo.getTitle() + " " + providerInfo.getSummary();

            // Add to navigation drawer
            mNavigationDrawer.getMenu()
                    .add(R.id.navigation_group_roots, providerHashCode, 0, title)
                    .setIcon(R.drawable.ic_fso_folder);
        }
    }

    /**
+228 −0
Original line number Diff line number Diff line
/*
 * 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.controllers;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.os.Environment;
import android.os.storage.StorageVolume;
import android.support.design.widget.NavigationView;
import android.text.TextUtils;
import android.util.Log;
import com.cyanogen.ambient.common.api.ResultCallback;
import com.cyanogen.ambient.storage.provider.StorageProviderInfo.ProviderInfoListResult;
import com.cyanogenmod.filemanager.FileManagerApplication;

import com.cyanogen.ambient.common.api.PendingResult;
import com.cyanogen.ambient.storage.StorageApi;
import com.cyanogen.ambient.storage.provider.StorageProviderInfo;
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.console.storageapi.StorageApiConsole;
import com.cyanogenmod.filemanager.model.Bookmark;
import com.cyanogenmod.filemanager.preferences.AccessMode;
import com.cyanogenmod.filemanager.util.StorageHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static com.cyanogenmod.filemanager.model.Bookmark.BOOKMARK_TYPE.SDCARD;
import static com.cyanogenmod.filemanager.model.Bookmark.BOOKMARK_TYPE.SECURE;
import static com.cyanogenmod.filemanager.model.Bookmark.BOOKMARK_TYPE.USB;

/**
 * NavigationDrawerController. This class is contains logic to add/remove and manage items in
 * the NavigationDrawer which uses android support libraries NavigationView.
 */
public class NavigationDrawerController
        implements ResultCallback<ProviderInfoListResult> {
    private static final String TAG = NavigationDrawerController.class.getSimpleName();
    private static boolean DEBUG = false;

    private static final String STR_USB = "usb"; // $NON-NLS-1$

    int[][] color_states = new int[][] {
            new int[] {android.R.attr.state_checked}, // checked
            new int[0] // default
    };

    // TODO: Replace with legitimate colors per item.
    int[] colors = new int[] {
            R.color.favorites_primary,
            Color.BLACK
    };

    private Context mCtx;
    private NavigationView mNavigationDrawer;
    private Map<Integer, StorageProviderInfo> mProvidersMap;
    private Map<Integer, Bookmark> mStorageBookmarks;

    public NavigationDrawerController(Context ctx, NavigationView navigationView) {
        mCtx = ctx;
        mNavigationDrawer = navigationView;
        mProvidersMap = new HashMap<Integer, StorageProviderInfo>();
        mStorageBookmarks = new HashMap<Integer, Bookmark>();

        ColorStateList colorStateList = new ColorStateList(color_states, colors);
        // TODO: Figure out why the following doesn't work correctly...
        mNavigationDrawer.setItemTextColor(colorStateList);
        mNavigationDrawer.setItemIconTintList(colorStateList);
    }

    @Override
    public void onResult(StorageProviderInfo.ProviderInfoListResult providerInfoListResult) {
        List<StorageProviderInfo> providerInfoList =
                providerInfoListResult.getProviderInfoList();
        if (providerInfoList == null) {
            Log.e(TAG, "no results returned");
            return;
        }
        if (DEBUG) Log.v(TAG, "got result(s)! " + providerInfoList.size());
        // TODO: Add to Navigation Drawer alphabetically
        for (StorageProviderInfo providerInfo : providerInfoList) {
            StorageApi sapi = StorageApi.getInstance();

            if (!providerInfo.needAuthentication()) {
                int providerHashCode = StorageApiConsole.getHashCodeFromProvider(providerInfo);

                // Verify console exists, or create one
                StorageApiConsole.registerStorageApiConsole(mCtx, sapi, providerInfo);

                // Add to navigation drawer controller
                addProviderInfoItem(providerHashCode, providerInfo);
            }
        }
    }

    public void loadNavigationDrawerItems() {
        // clear current special nav drawer items
        removeAllDynamicMenuItemsFromDrawer();

        // Show/hide root
        boolean showRoot = FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) != 0;
        mNavigationDrawer.getMenu().findItem(R.id.navigation_item_root_d).setVisible(showRoot);

        loadExternalStorageItems();
        StorageApi storageApi = StorageApi.getInstance();
        PendingResult<StorageProviderInfo.ProviderInfoListResult> pendingResult =
                storageApi.fetchProviders(this);
    }

    /**
     * Method that loads the secure digital card and usb storage menu items from the system.
     *
     * @return List<MenuItem> The storage items to be displayed
     */
    private void loadExternalStorageItems() {
        List<Bookmark> sdBookmarks = new ArrayList<Bookmark>();
        List<Bookmark> usbBookmarks = new ArrayList<Bookmark>();

        try {
            // Recovery sdcards and usb from storage manager
            StorageVolume[] volumes =
                    StorageHelper.getStorageVolumes(mCtx, 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);
                        Bookmark bookmark;
                        if (lowerPath.contains(STR_USB)) {
                            usbBookmarks.add(new Bookmark(USB, StorageHelper
                                    .getStorageVolumeDescription(mCtx,
                                            volume), path));
                        } else {
                            sdBookmarks.add(new Bookmark(SDCARD, StorageHelper
                                    .getStorageVolumeDescription(mCtx,
                                            volume), path));
                        }
                    }
                }
            }

            String localStorage = mCtx.getResources().getString(R.string.local_storage_path);

            // Load the bookmarks
            for (Bookmark b : sdBookmarks) {
                if (TextUtils.equals(b.getPath(), localStorage)) continue;
                int hash = b.hashCode();
                addMenuItemToDrawer(hash, b.getName(), R.drawable.ic_sdcard_drawable);
                mStorageBookmarks.put(hash, b);
            }
            for (Bookmark b : usbBookmarks) {
                int hash = b.hashCode();
                addMenuItemToDrawer(hash, b.getName(), R.drawable.ic_usb_drawable);
                mStorageBookmarks.put(hash, b);
            }
        }
        catch (Throwable ex) {
            Log.e(TAG, "Load filesystem bookmarks failed", ex); //$NON-NLS-1$
        }
    }

    private void addMenuItemToDrawer(int hash, String title, int iconDrawable) {
        if (mNavigationDrawer.getMenu().findItem(hash) == null) {
            mNavigationDrawer.getMenu()
                    .add(R.id.navigation_group_roots, hash, 0, title)
                    .setIcon(iconDrawable);
        }
    }

    public void removeMenuItemFromDrawer(int hash) {
        mNavigationDrawer.getMenu().removeItem(hash);
    }

    public void removeAllDynamicMenuItemsFromDrawer() {
        for (int key : mStorageBookmarks.keySet()) {
            removeMenuItemFromDrawer(key);
            mStorageBookmarks.remove(key);
        }
        for (int key : mProvidersMap.keySet()) {
            removeMenuItemFromDrawer(key);
            mProvidersMap.remove(key);
        }
    }

    public void addProviderInfoItem(int providerHashCode, StorageProviderInfo providerInfo) {
        // Concatenate title and summary
        // TODO: Change to two line menu items
        String title = providerInfo.getTitle() + " " + providerInfo.getSummary();

        mProvidersMap.put(providerHashCode, providerInfo);
        addMenuItemToDrawer(providerHashCode, title, R.drawable.ic_remote_drawable);
    }

    public StorageProviderInfo getProviderInfoFromMenuItem(int key) {
        return mProvidersMap.get(key);
    }

    public Bookmark getBookmarkFromMenuItem(int key) {
        return mStorageBookmarks.get(key);
    }
}
Loading