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

Commit 25e803b3 authored by Rohit Yengisetty's avatar Rohit Yengisetty
Browse files

CM File Manager : Populate results as they are found while searching

Eliminate the need to wait for a search to finish before accessing the
search results. The search results are streamed concurrently while
the search is still in progress.

Change-Id: I15f5b87ef4fbbbe9df2ee7a8428d9c812cadf159
parent cdb7c091
Loading
Loading
Loading
Loading
+26 −14
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@
    android:text="@string/search_no_results_msg"
    android:textAppearance="@style/primary_text_appearance_nohighlight"
    android:textSize="@dimen/title_text_size"
    android:visibility="visible" />
    android:visibility="gone" />

  <ProgressBar
    android:id="@+id/search_waiting"
@@ -46,12 +46,35 @@
    android:layout_alignParentBottom="true"
    android:background="@drawable/bg_material_statusbar" >

    <ProgressBar
      android:id="@+id/streaming_progress_bar"
      android:layout_width="@dimen/default_progress_width"
      android:layout_height="match_parent"
      android:layout_alignParentRight="true"
      android:layout_margin="@dimen/default_margin"
      android:indeterminate="true"
      android:indeterminateOnly="true" />

    <Spinner
      android:id="@+id/search_status_type_spinner"
      android:layout_width="wrap_content"
      android:layout_height="match_parent"
      android:layout_alignParentBottom="true"
      android:layout_alignParentRight="true"
      android:layout_marginBottom="@dimen/default_margin"
      android:layout_marginRight="@dimen/default_margin"
      android:gravity="left"
      android:textColor="@android:color/white"
      android:dropDownVerticalOffset="20dp"
      android:visibility="gone" />

    <TextView
      android:id="@+id/search_status_found_items"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      android:layout_alignParentTop="true"
      android:layout_toLeftOf="@id/streaming_progress_bar"
      android:layout_marginLeft="@dimen/default_margin"
      android:layout_marginTop="@dimen/default_margin"
      android:singleLine="true"
@@ -63,22 +86,12 @@
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_alignParentLeft="true"
      android:layout_toLeftOf="@id/streaming_progress_bar"
      android:layout_marginBottom="@dimen/default_margin"
      android:layout_marginLeft="@dimen/default_margin"
      android:singleLine="true"
      android:textAppearance="@style/secondary_text_appearance" />

    <Spinner
      android:id="@+id/search_status_type_spinner"
      android:layout_width="wrap_content"
      android:layout_height="match_parent"
      android:layout_alignParentBottom="true"
      android:layout_alignParentRight="true"
      android:layout_marginBottom="@dimen/default_margin"
      android:layout_marginRight="@dimen/default_margin"
      android:gravity="left"
      android:textColor="@android:color/white"
      android:dropDownVerticalOffset="20dp" />

  </RelativeLayout>

@@ -87,7 +100,6 @@
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/search_status"
    android:drawSelectorOnTop="true"
    android:visibility="gone" />
    android:drawSelectorOnTop="true" />

</RelativeLayout>
+1 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@

    <!-- The progress height -->
    <dimen name="default_progress_height">48dp</dimen>
    <dimen name="default_progress_width">48dp</dimen>

    <!-- Theme button min width -->
    <dimen name="themes_min_width_button">300dp</dimen>
+75 −144
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.os.Parcelable;
import android.preference.PreferenceActivity;
@@ -42,7 +44,6 @@ import android.widget.AdapterView.OnItemLongClickListener;

import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Spinner;
@@ -69,11 +70,9 @@ import com.cyanogenmod.filemanager.preferences.AccessMode;
import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
import com.cyanogenmod.filemanager.preferences.Preferences;
import com.cyanogenmod.filemanager.providers.RecentSearchesContentProvider;
import com.cyanogenmod.filemanager.tasks.SearchResultDrawingAsyncTask;
import com.cyanogenmod.filemanager.ui.ThemeManager;
import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
import com.cyanogenmod.filemanager.ui.dialogs.ActionsDialog;
import com.cyanogenmod.filemanager.ui.dialogs.MessageProgressDialog;
import com.cyanogenmod.filemanager.ui.policy.DeleteActionPolicy;
import com.cyanogenmod.filemanager.ui.policy.IntentsActionPolicy;
import com.cyanogenmod.filemanager.ui.widgets.ButtonItem;
@@ -87,6 +86,7 @@ import com.cyanogenmod.filemanager.util.ExceptionUtil.OnRelaunchCommandResult;
import com.cyanogenmod.filemanager.util.FileHelper;
import com.cyanogenmod.filemanager.util.MimeTypeHelper;
import com.cyanogenmod.filemanager.util.MimeTypeHelper.MimeTypeCategory;
import com.cyanogenmod.filemanager.util.SearchHelper;
import com.cyanogenmod.filemanager.util.StorageHelper;

import java.io.FileNotFoundException;
@@ -155,7 +155,7 @@ public class SearchActivity extends Activity
                            // Recreate the adapter
                            int pos = SearchActivity.
                                        this.mSearchListView.getFirstVisiblePosition();
                            drawResults();
                            mAdapter.notifyDataSetChanged();
                            SearchActivity.this.mSearchListView.setSelection(pos);
                            return;
                        }
@@ -227,12 +227,8 @@ public class SearchActivity extends Activity
         */
        @Override
        public void onConcurrentAsyncStart() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    SearchActivity.this.toggleResults(false, false);
                }
            });
            mSearchInProgress = true;
            mAdapter.startStreaming();
        }

        /**
@@ -240,21 +236,19 @@ public class SearchActivity extends Activity
         */
        @Override
        public void onConcurrentAsyncEnd(boolean cancelled) {
            mSearchInProgress = false;
            mSearchListView.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        //Dismiss the dialog
                        if (SearchActivity.this.mDialog != null) {
                            SearchActivity.this.mDialog.dismiss();
                        mAdapter.stopStreaming();
                        int resultsSize = mAdapter.resultsSize();
                        mStreamingSearchProgress.setVisibility(View.INVISIBLE);
                        if (mMimeTypeCategories.size() > 1) {
                            mMimeTypeSpinner.setVisibility(View.VISIBLE);
                        }

                        // Resolve the symlinks
                        FileHelper.resolveSymlinks(
                                SearchActivity.this, SearchActivity.this.mResultList);

                        // Draw the results
                        drawResults();
                        mSearchListView.setVisibility(resultsSize > 0 ? View.VISIBLE : View.GONE);
                        mEmptyListMsg.setVisibility(resultsSize > 0 ? View.GONE : View.VISIBLE);

                    } catch (Throwable ex) {
                        Log.e(TAG, "onAsyncEnd method fails", ex); //$NON-NLS-1$
@@ -270,11 +264,13 @@ public class SearchActivity extends Activity
        @SuppressWarnings("unchecked")
        public void onConcurrentPartialResult(final Object partialResults) {
            //Saved in the global result list, for save at the end
            FileSystemObject result = null;
            if (partialResults instanceof FileSystemObject) {
                FileSystemObject fso = (FileSystemObject) partialResults;
                if (mMimeTypeCategories == null || mMimeTypeCategories.contains(MimeTypeHelper
                        .getCategory(SearchActivity.this, fso))) {
                    SearchActivity.this.mResultList.add((FileSystemObject) partialResults);
                    showSearchResult((FileSystemObject) partialResults);
                }
            } else {
                List<FileSystemObject> fsoList = (List<FileSystemObject>) partialResults;
@@ -282,6 +278,7 @@ public class SearchActivity extends Activity
                    if (mMimeTypeCategories == null || mMimeTypeCategories.contains(MimeTypeHelper
                            .getCategory(SearchActivity.this, fso))) {
                        SearchActivity.this.mResultList.add(fso);
                        showSearchResult(fso);
                    }
                }
            }
@@ -290,10 +287,17 @@ public class SearchActivity extends Activity
            mSearchListView.post(new Runnable() {
                @Override
                public void run() {
                    if (SearchActivity.this.mDialog != null) {
                        int progress = SearchActivity.this.mResultList.size();
                        setProgressMsg(progress);
                    }
                    int progress = mAdapter.resultsSize();
                    String foundItems =
                            getResources().
                                    getQuantityString(
                                            R.plurals.search_found_items, progress,
                                            Integer.valueOf(progress) );
                    mSearchFoundItems.setText(
                            getString(
                                    R.string.search_found_items_in_directory,
                                    foundItems,
                                    mSearchDirectory));
                }
            });
        }
@@ -314,10 +318,6 @@ public class SearchActivity extends Activity
        }
    };

    /**
     * @hide
     */
    MessageProgressDialog mDialog = null;
    /**
     * @hide
     */
@@ -361,8 +361,6 @@ public class SearchActivity extends Activity
     */
    SearchInfoParcelable mRestoreState;

    private SearchResultDrawingAsyncTask mDrawingSearchResultTask;

    /**
     * @hide
     */
@@ -373,6 +371,10 @@ public class SearchActivity extends Activity
     */
    HashSet<MimeTypeCategory> mMimeTypeCategories;

    private SearchResultAdapter mAdapter;
    private ProgressBar mStreamingSearchProgress;
    private boolean mSearchInProgress;

    /**
     * {@inheritDoc}
     */
@@ -543,16 +545,6 @@ public class SearchActivity extends Activity
        configuration.setImageResource(R.drawable.ic_material_light_config);
        configuration.setVisibility(View.VISIBLE);
        actionBar.setCustomView(customTitle);

        // Specify a SpinnerAdapter to populate the dropdown list.
        Spinner typeSpinner = (Spinner) findViewById(R.id.search_status_type_spinner);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                R.layout.search_spinner_item,
                MimeTypeHelper.MimeTypeCategory.getFriendlyLocalizedNames(this));
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        typeSpinner.setAdapter(adapter);
        typeSpinner.setOnItemSelectedListener(this);
    }

    /**
@@ -580,12 +572,25 @@ public class SearchActivity extends Activity

        //Other components
        this.mSearchWaiting = (ProgressBar)findViewById(R.id.search_waiting);
        mStreamingSearchProgress = (ProgressBar) findViewById(R.id.streaming_progress_bar);
        mStreamingSearchProgress.getIndeterminateDrawable()
                .setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);

        this.mSearchFoundItems = (TextView)findViewById(R.id.search_status_found_items);
        setFoundItems(0, ""); //$NON-NLS-1$
        this.mSearchTerms = (TextView)findViewById(R.id.search_status_query_terms);
        this.mSearchTerms.setText(
                Html.fromHtml(getString(R.string.search_terms, ""))); //$NON-NLS-1$
        this.mMimeTypeSpinner = (Spinner) findViewById(R.id.search_status_type_spinner);

        // populate Mime Types spinner for search results filtering
        mMimeTypeSpinner = (Spinner) findViewById(R.id.search_status_type_spinner);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                R.layout.search_spinner_item,
                MimeTypeHelper.MimeTypeCategory.getFriendlyLocalizedNames(this));
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mMimeTypeSpinner.setAdapter(adapter);
        mMimeTypeSpinner.setOnItemSelectedListener(this);
    }

    /**
@@ -625,23 +630,6 @@ public class SearchActivity extends Activity
            }
        }

        //Stop any pending action
        try {
            if (SearchActivity.this.mDrawingSearchResultTask != null
                    && SearchActivity.this.mDrawingSearchResultTask.isRunning()) {
                SearchActivity.this.mDrawingSearchResultTask.cancel(true);
            }
        } catch (Throwable ex2) {
            /**NON BLOCK**/
        }
        try {
            if (SearchActivity.this.mDialog != null) {
                SearchActivity.this.mDialog.dismiss();
            }
        } catch (Throwable ex2) {
            /**NON BLOCK**/
        }

        //If data is not present, use root directory to do the search
        this.mSearchDirectory = FileHelper.ROOT_DIRECTORY;
        String searchDirectory = getIntent()
@@ -763,10 +751,10 @@ public class SearchActivity extends Activity
            ((SearchResultAdapter)this.mSearchListView.getAdapter()).dispose();
        }
        this.mResultList = new ArrayList<FileSystemObject>();
        SearchResultAdapter adapter =
        mAdapter =
                new SearchResultAdapter(this,
                        new ArrayList<SearchResult>(), R.layout.search_item, this.mQuery);
        this.mSearchListView.setAdapter(adapter);
        this.mSearchListView.setAdapter(mAdapter);

        //Set terms
        if (mMimeTypeCategories == null) {
@@ -787,43 +775,6 @@ public class SearchActivity extends Activity
            @Override
            public void run() {
                try {
                    //Retrieve the terms of the search
                    String label = getString(R.string.searching_action_label);

                    //Show a dialog for the progress
                    SearchActivity.this.mDialog =
                            new MessageProgressDialog(
                                    SearchActivity.this,
                                    0,
                                    R.string.searching, label, true);
                    // Initialize the
                    setProgressMsg(0);

                    // Set the cancel listener
                    SearchActivity.this.mDialog.setOnCancelListener(
                            new MessageProgressDialog.OnCancelListener() {
                                @Override
                                public boolean onCancel() {
                                    //User has requested the cancellation of the search
                                    //Broadcast the cancellation
                                    if (!SearchActivity.this.mExecutable.isCancelled()) {
                                        if (SearchActivity.this.mExecutable.cancel()) {
                                            ListAdapter listAdapter =
                                                    SearchActivity.
                                                            this.mSearchListView.getAdapter();
                                            if (listAdapter != null) {
                                                SearchActivity.this.toggleResults(
                                                        listAdapter.getCount() > 0, true);
                                            }
                                            return true;
                                        }
                                        return false;
                                    }
                                    return true;
                                }
                            });
                    SearchActivity.this.mDialog.show();

                    // Execute the query (search in background)
                    SearchActivity.this.mExecutable =
                            CommandHelper.findFiles(
@@ -840,13 +791,6 @@ public class SearchActivity extends Activity
                    } catch (Throwable ex2) {
                        /**NON BLOCK**/
                    }
                    try {
                        if (SearchActivity.this.mDialog != null) {
                            SearchActivity.this.mDialog.dismiss();
                        }
                    } catch (Throwable ex2) {
                        /**NON BLOCK**/
                    }

                    //Capture the exception
                    Log.e(TAG, "Search failed", ex); //$NON-NLS-1$
@@ -859,6 +803,27 @@ public class SearchActivity extends Activity
        });
    }

    /**
     * Ensures the search result meets user preferences and passes it to the adapter for display
     *
     * @param result FileSystemObject that matches the search result criteria
     */
    private void showSearchResult(FileSystemObject result) {
        // check against user's display preferences
        if ( !FileHelper.compliesWithDisplayPreferences(result, null, mChRooted) ) {
            return;
        }

        // resolve sym links
        FileHelper.resolveSymlink(this, result);

        // convert to search result
        SearchResult searchResult = SearchHelper.convertToResult(result, mQuery);

        // add to adapter
        mAdapter.addNewItem(searchResult);
    }

    /**
     * Method that restore the activity from the cached data.
     */
@@ -1028,6 +993,11 @@ public class SearchActivity extends Activity
     */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // cancel search query if in progress
        // *need* to do this as the async query holds a lock on the Console and we need the Console
        // to gather additional file info in order to process the click event
        if (mSearchInProgress) mExecutable.cancel();

        try {
            SearchResult result = ((SearchResultAdapter)parent.getAdapter()).getItem(position);
            FileSystemObject fso = result.getFso();
@@ -1145,7 +1115,6 @@ public class SearchActivity extends Activity
                for (int i = 0; i < cc; i++) {
                    this.mResultList.add(results.get(i).getFso());
                }
                drawResults();
            }
        }
    }
@@ -1192,10 +1161,6 @@ public class SearchActivity extends Activity
        boolean finish = true;
        if (cancelled) {
            final Intent intent =  new Intent();
            if (SearchActivity.this.mDrawingSearchResultTask != null
                    && SearchActivity.this.mDrawingSearchResultTask.isRunning()) {
                SearchActivity.this.mDrawingSearchResultTask.cancel(true);
            }
            if (this.mRestoreState != null) {
                Bundle bundle = new Bundle();
                bundle.putParcelable(NavigationActivity.EXTRA_SEARCH_LAST_SEARCH_DATA,
@@ -1290,25 +1255,6 @@ public class SearchActivity extends Activity
        return false;
    }

    /**
     * Method that draw the results in the listview
     * @hide
     */
    void drawResults() {
        //Toggle results
        this.toggleResults(this.mResultList.size() > 0, true);
        setFoundItems(this.mResultList.size(), this.mSearchDirectory);

        //Create the task for drawing the data
        this.mDrawingSearchResultTask =
                                new SearchResultDrawingAsyncTask(
                                        this.mSearchListView,
                                        this.mSearchWaiting,
                                        this.mResultList,
                                        this.mQuery);
        this.mDrawingSearchResultTask.execute();
    }

    /**
     * Method that creates a {@link SearchInfoParcelable} reference from
     * the current data.
@@ -1323,21 +1269,6 @@ public class SearchActivity extends Activity
        return parcel;
    }

    /**
     * Method that set the progress of the search
     *
     * @param progress The progress
     * @hide
     */
    void setProgressMsg(int progress) {
        String msg =
                getResources().getQuantityString(
                        R.plurals.search_found_items,
                        progress,
                        Integer.valueOf(progress));
        SearchActivity.this.mDialog.setProgress(Html.fromHtml(msg));
    }

    /**
     * Method that applies the current theme to the activity
     * @hide
+115 −12

File changed.

Preview size limit exceeded, changes collapsed.

+0 −215

File deleted.

Preview size limit exceeded, changes collapsed.

Loading