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

Commit 6d01dfef authored by Raj Yengisetty's avatar Raj Yengisetty
Browse files

Implement StorageApiConsole discovery for listFiles

Copy/Move: use async task to listFiles

Change-Id: Ied51d669b266af324e5009a3e28558f81caa1287
parent 1e5e47b4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -41,4 +41,6 @@
    <integer name="default_underline_indicator_fade_length">400</integer>
    <integer name="default_title_indicator_line_position">0</integer>

    <!-- Timeout used for waiting on Storage API to return document list -->
    <integer name="storageapi_timeout">5000</integer>
</resources>
+17 −27
Original line number Diff line number Diff line
@@ -254,6 +254,7 @@ public class MainActivity extends ActionBarActivity
        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:
@@ -262,6 +263,7 @@ 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);
                setCurrentFragment(FragmentType.NAVIGATION);
                break;
            case R.id.navigation_item_root_d:
@@ -289,19 +291,14 @@ public class MainActivity extends ActionBarActivity
                openSettings();
                break;
            default:
                if (DEBUG) {
                    Log.d(TAG, String.format("onNavigationItemSelected::default (%d)", id));

                if (DEBUG) Log.d(TAG, String.format("onNavigationItemSelected::default (%d)", id));
                // Check for item id in remote roots
                StorageProviderInfo providerInfo = mProvidersMap.get(id);
                    Log.v(TAG, "providerInfo " + providerInfo.hashCode());
                    Log.v(TAG, "providerInfo.package " + providerInfo.getPackage());
                    Log.v(TAG, "providerInfo.authority " + providerInfo.getAuthority());
                    Log.v(TAG, "providerInfo.needsAuth " + providerInfo.needAuthentication());
                    Log.v(TAG, "providerInfo.title " + providerInfo.getTitle());
                    Log.v(TAG, "providerInfo.summary " + providerInfo.getSummary());
                    Log.v(TAG, "providerInfo.root " + providerInfo.getRootDocumentId());
                }
                getIntent().putExtra(EXTRA_NAVIGATE_TO,
                        StorageApiConsole.constructStorageApiFilePathFromProvider(
                                providerInfo.getRootDocumentId(),
                                StorageApiConsole.getHashCodeFromProvider(providerInfo)));
                setCurrentFragment(FragmentType.NAVIGATION);
                break;
        }
        mDrawerLayout.closeDrawers();
@@ -319,28 +316,21 @@ public class MainActivity extends ActionBarActivity
        if (DEBUG) Log.v(TAG, "got result(s)! " + providerInfoList.size());
        for (StorageProviderInfo providerInfo : providerInfoList) {
            StorageApi sapi = StorageApi.newInstance(MainActivity.this);
            sapi.getMetadata(providerInfo, providerInfo.getRootDocumentId(), true);
            if (DEBUG) {
                Log.v(TAG, "providerInfo " + providerInfo.hashCode());
                Log.v(TAG, "providerInfo.package " + providerInfo.getPackage());
                Log.v(TAG, "providerInfo.authority " + providerInfo.getAuthority());
                Log.v(TAG, "providerInfo.needsAuth " + providerInfo.needAuthentication());
                Log.v(TAG, "providerInfo.title " + providerInfo.getTitle());
                Log.v(TAG, "providerInfo.summary " + providerInfo.getSummary());
                Log.v(TAG, "providerInfo.root " + providerInfo.getRootDocumentId());
            }
            final String rootTitle = String.format("%s %s", providerInfo.getTitle(),
                    providerInfo.getSummary());

            // Add provider to map
            mProvidersMap.put(rootTitle.hashCode(), providerInfo);
            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, rootTitle.hashCode(), 0, rootTitle)
                    .add(R.id.navigation_group_roots, providerHashCode, 0, title)
                    .setIcon(R.drawable.ic_fso_folder);
        }
    }
+2 −0
Original line number Diff line number Diff line
@@ -143,6 +143,8 @@ public class ListCommand extends Program implements ListExecutable {
                    fso = new Directory(
                            virtualMountPoint.getName(),
                            getConsole().getVirtualMountPoint().getParent(),
                            null,
                            null,
                            fso.getUser(), fso.getGroup(), fso.getPermissions(),
                            fso.getLastAccessedTime(),
                            fso.getLastModifiedTime(),
+178 −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.commands.storageapi;

import android.text.TextUtils;
import android.util.Log;

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.StorageApi.Document;
import com.cyanogen.ambient.storage.StorageApi.Document.DocumentResult;
import com.cyanogen.ambient.storage.provider.StorageProviderInfo;
import com.cyanogenmod.filemanager.commands.ListExecutable;
import com.cyanogenmod.filemanager.console.ExecutionException;
import com.cyanogenmod.filemanager.console.InsufficientPermissionsException;
import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
import com.cyanogenmod.filemanager.console.storageapi.StorageApiConsole;
import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.model.ParentDirectory;
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.util.FileHelper;

import java.io.File;
import java.util.ArrayList;
import java.util.List;


/**
 * A class for list information about files and directories.
 */
public class ListCommand extends Program implements ListExecutable {
    private static final String TAG = ListCommand.class.getSimpleName();

    private final StorageApiConsole mConsole;
    private final String mSrc;
    private final LIST_MODE mMode;
    private final List<FileSystemObject> mFiles;
    private final Object mSync = new Object();
    private boolean mFinished = false;

    /**
     * Constructor of <code>ListCommand</code>. List mode.
     *
     * @param src The file system object to be listed
     * @param mode The mode of listing
     */
    public ListCommand(StorageApiConsole console, String src, LIST_MODE mode) {
        super();
        this.mConsole = console;
        this.mSrc = StorageApiConsole.getProviderPathFromFullPath(src);
        this.mMode = mode;
        this.mFiles = new ArrayList<FileSystemObject>();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<FileSystemObject> getResult() {
        if (!mFinished) {
            synchronized (mSync) {
                try {
                    mSync.wait(R.integer.storageapi_timeout);
                } catch (InterruptedException e) {
                    Log.e(TAG, "Result timeout. No valid results returned."); //$NON-NLS-1$
                }
            }
        }
        return this.mFiles;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void execute()
            throws InsufficientPermissionsException, NoSuchFileOrDirectory, ExecutionException {
        if (isTrace()) {
            Log.v(TAG,
                    String.format("Listing %s. Mode: %s", //$NON-NLS-1$
                            this.mSrc, this.mMode));
        }

        StorageApi storageApi = mConsole.getStorageApi();
        StorageProviderInfo storageProviderInfo = mConsole.getStorageProviderInfo();
        if (storageApi == null) {
            return;
        } else if (storageProviderInfo == null || TextUtils.isEmpty(mSrc)) {
            return;
        }

        PendingResult<DocumentResult> pendingResult =
                storageApi.getMetadata(storageProviderInfo, mSrc, true);
        pendingResult.setResultCallback(new ResultCallback<DocumentResult>() {
            @Override
            public void onResult(DocumentResult documentResult) {
                if (documentResult == null) {
                    Log.e(TAG, "Result: FAIL. No results returned."); //$NON-NLS-1$
                    return;
                }
                try {
                    processDocumentResult(documentResult);
                } catch (Exception e) {
                    Log.e(TAG, "Result: Error parsing results. e=" + e); //$NON-NLS-1$
                }
                synchronized (mSync) {
                    mSync.notify();
                }
                mFinished = true;

                if (isTrace()) {
                    Log.v(TAG, "Result: OK"); //$NON-NLS-1$
                }
            }
        });
    }

    private void processDocumentResult(DocumentResult result)
            throws InsufficientPermissionsException, NoSuchFileOrDirectory, ExecutionException {
        Document current = result.getDocument();
        if (current == null) {
            if (isTrace()) {
                Log.v(TAG, "Result: FAIL. NoSuchFileOrDirectory"); //$NON-NLS-1$
            }
            throw new NoSuchFileOrDirectory(this.mSrc);
        }
        int hash = StorageApiConsole.getHashCodeFromProvider(mConsole.getStorageProviderInfo());
        String providerPrefix = StorageApiConsole.constructStorageApiPrefixFromHash(hash);
        if (this.mMode.compareTo(LIST_MODE.DIRECTORY) == 0) {
            List<Document> documents = current.getContents();
            if (documents != null && !documents.isEmpty()) {
                for (Document document : documents) {
                    FileSystemObject fso =
                            FileHelper.createFileSystemObject(document, providerPrefix);
                    if (fso != null) {
                        if (isTrace()) {
                            Log.v(TAG, String.valueOf(fso));
                        }
                        this.mFiles.add(fso);
                    }
                }
            }

            // If current is not root, add parent directory to file list (..)
            if (!TextUtils.equals(current.getId(), current.getParentId()) &&
                    this.mMode.compareTo(LIST_MODE.DIRECTORY) == 0) {
                Log.d(TAG,"Adding parentId=" + current.getParentId());
                this.mFiles.add(0, new ParentDirectory(current.getParentId(), providerPrefix));
            }

        } else {
            // Build the parent information
            FileSystemObject fso = FileHelper.createFileSystemObject(current, providerPrefix);
            if (fso != null) {
                if (isTrace()) {
                    Log.v(TAG, String.valueOf(fso));
                }
                this.mFiles.add(fso);
            }
        }
    }

}
+1 −2
Original line number Diff line number Diff line
@@ -225,8 +225,7 @@ public class StorageApiExecutableCreator implements ExecutableCreator {
    @Override
    public ListExecutable createListExecutable(String src)
            throws CommandNotFoundException {
        throw new CommandNotFoundException("Not implemented"); //$NON-NLS-1$
        //return new ListCommand(src, LIST_MODE.DIRECTORY);
        return new ListCommand(mConsole, src, LIST_MODE.DIRECTORY);
    }

    /**
Loading