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

Commit 3e1bfdde authored by Jorge Ruesga's avatar Jorge Ruesga
Browse files

CMFM: Fix more deadlocks



Change-Id: If5895b6c40708e2417595b7b2e5b676c10ce6f6c
Signed-off-by: default avatarJorge Ruesga <jorge@ruesga.com>
parent e38d9f1f
Loading
Loading
Loading
Loading
+0 −12
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.cyanogenmod.filemanager.activities.preferences;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
@@ -50,17 +49,6 @@ public class ThemesPreferenceFragment extends TitlePreferenceFragment {
                            key,
                            String.valueOf(newValue)));
            }

            // Notify to all activities that the theme has changed
            Intent intent = new Intent(FileManagerSettings.INTENT_THEME_CHANGED);
            intent.putExtra(FileManagerSettings.EXTRA_THEME_ID, (String)newValue);
            getActivity().sendBroadcast(intent);

            //Wait for allow activities to apply the theme, prior to finish settings
            try {
                Thread.sleep(250L);
            } catch (Throwable e) {/**NON BLOCK**/}
            getActivity().finish();
            return true;
        }
    };
+6 −18
Original line number Diff line number Diff line
@@ -275,23 +275,6 @@ public class FileSystemObjectAdapter
                viewHolder.mBtCheck = (ImageButton)v.findViewById(RESOURCE_ITEM_CHECK);
                viewHolder.mBtCheck.setVisibility(View.GONE);
            }

            // Apply the current theme
            if (this.mPickable) {
                theme.setBackgroundDrawable(
                        getContext(), v, "background_drawable"); //$NON-NLS-1$
            }
            theme.setTextColor(
                    getContext(), viewHolder.mTvName, "text_color"); //$NON-NLS-1$
            if (viewHolder.mTvSummary != null) {
                theme.setTextColor(
                        getContext(), viewHolder.mTvSummary, "text_color"); //$NON-NLS-1$
            }
            if (viewHolder.mTvSize != null) {
                theme.setTextColor(
                        getContext(), viewHolder.mTvSize, "text_color"); //$NON-NLS-1$
            }

            v.setTag(viewHolder);
        }

@@ -300,9 +283,11 @@ public class FileSystemObjectAdapter

        //Retrieve the view holder
        ViewHolder viewHolder = (ViewHolder)v.getTag();
        if (this.mPickable) {
            theme.setBackgroundDrawable(getContext(), v, "background_drawable"); //$NON-NLS-1$
        }

        //Set the data

        if (convertView != null) {
            // Cancel load for previous usage
            mIconHolder.cancelLoad(viewHolder.mIvIcon);
@@ -310,11 +295,14 @@ public class FileSystemObjectAdapter
        mIconHolder.loadDrawable(viewHolder.mIvIcon, getItem(position), dataHolder.mDwIcon);

        viewHolder.mTvName.setText(dataHolder.mName);
        theme.setTextColor(getContext(), viewHolder.mTvName, "text_color"); //$NON-NLS-1$
        if (viewHolder.mTvSummary != null) {
            viewHolder.mTvSummary.setText(dataHolder.mSummary);
            theme.setTextColor(getContext(), viewHolder.mTvSummary, "text_color"); //$NON-NLS-1$
        }
        if (viewHolder.mTvSize != null) {
            viewHolder.mTvSize.setText(dataHolder.mSize);
            theme.setTextColor(getContext(), viewHolder.mTvSize, "text_color"); //$NON-NLS-1$
        }
        if (!this.mPickable) {
            viewHolder.mBtCheck.setVisibility(
+281 −301
Original line number Diff line number Diff line
@@ -203,6 +203,198 @@ public class NavigationView extends RelativeLayout implements
        }
    };

    private class NavigationTask extends AsyncTask<String, Integer, List<FileSystemObject>> {
        private final boolean mUseCurrent;
        private final boolean mAddToHistory;
        private final boolean mReload;
        private boolean mHasChanged;
        private boolean mIsNewHistory;
        private String mNewDirChecked;
        private final SearchInfoParcelable mSearchInfo;
        private final FileSystemObject mScrollTo;

        public NavigationTask(boolean useCurrent, boolean addToHistory, boolean reload,
                SearchInfoParcelable searchInfo, FileSystemObject scrollTo) {
            super();
            this.mUseCurrent = useCurrent;
            this.mAddToHistory = addToHistory;
            this.mSearchInfo = searchInfo;
            this.mReload = reload;
            this.mScrollTo = scrollTo;
        }

        /**
         * {@inheritDoc}
         */
        @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]);

            //Check that it is really necessary change the directory
            if (!mReload && NavigationView.this.mCurrentDir != null &&
                    NavigationView.this.mCurrentDir.compareTo(mNewDirChecked) == 0) {
                return null;
            }

            mHasChanged = !(NavigationView.this.mCurrentDir != null &&
                    NavigationView.this.mCurrentDir.compareTo(mNewDirChecked) == 0);
            mIsNewHistory = (NavigationView.this.mCurrentDir != null);

            try {
                //Reset the custom title view and returns to breadcrumb
                if (NavigationView.this.mTitle != null) {
                    NavigationView.this.mTitle.post(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                NavigationView.this.mTitle.restoreView();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }


                //Start of loading data
                if (NavigationView.this.mBreadcrumb != null) {
                    try {
                        NavigationView.this.mBreadcrumb.startLoading();
                    } catch (Throwable ex) {
                        /**NON BLOCK**/
                    }
                }

                //Get the files, resolve links and apply configuration
                //(sort, hidden, ...)
                List<FileSystemObject> files = NavigationView.this.mFiles;
                if (!mUseCurrent) {
                    files = CommandHelper.listFiles(getContext(), mNewDirChecked, null);
                }
                return files;

            } catch (final ConsoleAllocException e) {
                //Show exception and exists
                NavigationView.this.post(new Runnable() {
                    @Override
                    public void run() {
                        Context ctx = getContext();
                        Log.e(TAG, ctx.getString(
                                R.string.msgs_cant_create_console), e);
                        DialogHelper.showToast(ctx,
                                R.string.msgs_cant_create_console,
                                Toast.LENGTH_LONG);
                        ((Activity)ctx).finish();
                    }
                });

            } catch (Exception ex) {
                //End of loading data
                if (NavigationView.this.mBreadcrumb != null) {
                    try {
                        NavigationView.this.mBreadcrumb.endLoading();
                    } catch (Throwable ex2) {
                        /**NON BLOCK**/
                    }
                }

                //Capture exception (attach task, and use listener to do the anim)
                ExceptionUtil.attachAsyncTask(
                    ex,
                    new AsyncTask<Object, Integer, Boolean>() {
                        private List<FileSystemObject> mTaskFiles = null;
                        @Override
                        @SuppressWarnings({
                                "unchecked", "unqualified-field-access"
                        })
                        protected Boolean doInBackground(Object... taskParams) {
                            mTaskFiles = (List<FileSystemObject>)taskParams[0];
                            return Boolean.TRUE;
                        }

                        @Override
                        @SuppressWarnings("unqualified-field-access")
                        protected void onPostExecute(Boolean result) {
                            if (!result.booleanValue()) {
                                return;
                            }
                            onPostExecuteTask(
                                    mTaskFiles, mAddToHistory, mIsNewHistory, mHasChanged,
                                    mSearchInfo, mNewDirChecked, mScrollTo);
                        }
                    });
                final OnRelaunchCommandResult exListener =
                        new OnRelaunchCommandResult() {
                    @Override
                    public void onSuccess() {
                        done();
                    }
                    @Override
                    public void onFailed(Throwable cause) {
                        done();
                    }
                    @Override
                    public void onCancelled() {
                        done();
                    }
                    private void done() {
                        // Do animation
                        fadeEfect(false);
                    }
                };
                ExceptionUtil.translateException(
                        getContext(), ex, false, true, exListener);
            }
            return null;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected void onCancelled(List<FileSystemObject> result) {
            onCancelled();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected void onPostExecute(List<FileSystemObject> files) {
            // This means an exception. This method will be recalled then
            if (files != null) {
                onPostExecuteTask(files, mAddToHistory, mIsNewHistory, mHasChanged,
                        mSearchInfo, mNewDirChecked, mScrollTo);

                // Do animation
                fadeEfect(false);
            }
        }

        /**
         * Method that performs a fade animation.
         *
         * @param out Fade out (true); Fade in (false)
         */
        void fadeEfect(final boolean out) {
            Activity activity = (Activity)getContext();
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Animation fadeAnim = out ?
                            new AlphaAnimation(1, 0) :
                            new AlphaAnimation(0, 1);
                    fadeAnim.setDuration(50L);
                    fadeAnim.setFillAfter(true);
                    fadeAnim.setInterpolator(new AccelerateInterpolator());
                    NavigationView.this.startAnimation(fadeAnim);
                }
            });
        }
   };

    private int mId;
    private String mCurrentDir;
    private NavigationLayoutMode mCurrentMode;
@@ -212,9 +404,6 @@ public class NavigationView extends RelativeLayout implements
    List<FileSystemObject> mFiles;
    private FileSystemObjectAdapter mAdapter;

    private boolean mChangingDir;
    private final Object mSync = new Object();

    private OnHistoryListener mOnHistoryListener;
    private OnNavigationSelectionChangedListener mOnNavigationSelectionChangedListener;
    private OnNavigationRequestMenuListener mOnNavigationRequestMenuListener;
@@ -314,12 +503,6 @@ public class NavigationView extends RelativeLayout implements
     * @return boolean If can restore
     */
    public boolean onRestoreState(NavigationViewInfoParcelable info) {
        synchronized (mSync) {
            if (mChangingDir) {
                return false;
            }
        }

        //Restore the data
        this.mId = info.getId();
        this.mCurrentDir = info.getCurrentDir();
@@ -609,7 +792,6 @@ public class NavigationView extends RelativeLayout implements
     */
    @SuppressWarnings("unchecked")
    public void changeViewMode(final NavigationLayoutMode newMode) {
        synchronized (this.mSync) {
        //Check that it is really necessary change the mode
        if (this.mCurrentMode != null && this.mCurrentMode.compareTo(newMode) == 0) {
            return;
@@ -711,7 +893,6 @@ public class NavigationView extends RelativeLayout implements
            }
        }
    }
    }

    /**
     * Method that removes a {@link FileSystemObject} from the view
@@ -787,210 +968,9 @@ public class NavigationView extends RelativeLayout implements
            final String newDir, final boolean addToHistory,
            final boolean reload, final boolean useCurrent,
            final SearchInfoParcelable searchInfo, final FileSystemObject scrollTo) {

        // Check navigation security (don't allow to go outside the ChRooted environment if one
        // is created)
        final String fNewDir = checkChRootedNavigation(newDir);

        // Wait to finalization
        synchronized (this.mSync) {
            if (mChangingDir) {
                try {
                    mSync.wait();
                } catch (InterruptedException iex) {
                    // Ignore
                }
            }
            mChangingDir = true;
        }

        //Check that it is really necessary change the directory
        if (!reload && this.mCurrentDir != null && this.mCurrentDir.compareTo(fNewDir) == 0) {
            synchronized (this.mSync) {
                mChangingDir = false;
                mSync.notify();
            }
            return;
        }

        final boolean hasChanged =
                !(this.mCurrentDir != null && this.mCurrentDir.compareTo(fNewDir) == 0);
        final boolean isNewHistory = (this.mCurrentDir != null);

        //Execute the listing in a background process
        AsyncTask<String, Integer, List<FileSystemObject>> task =
                new AsyncTask<String, Integer, List<FileSystemObject>>() {
                    /**
                     * {@inheritDoc}
                     */
                    @Override
                    protected List<FileSystemObject> doInBackground(String... params) {
                        try {
                            //Reset the custom title view and returns to breadcrumb
                            if (NavigationView.this.mTitle != null) {
                                NavigationView.this.mTitle.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            NavigationView.this.mTitle.restoreView();
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                    }
                                });
                            }


                            //Start of loading data
                            if (NavigationView.this.mBreadcrumb != null) {
                                try {
                                    NavigationView.this.mBreadcrumb.startLoading();
                                } catch (Throwable ex) {
                                    /**NON BLOCK**/
                                }
                            }

                            //Get the files, resolve links and apply configuration
                            //(sort, hidden, ...)
                            List<FileSystemObject> files = NavigationView.this.mFiles;
                            if (!useCurrent) {
                                files = CommandHelper.listFiles(getContext(), fNewDir, null);
                            }
                            return files;

                        } catch (final ConsoleAllocException e) {
                            //Show exception and exists
                            NavigationView.this.post(new Runnable() {
                                @Override
                                public void run() {
                                    Context ctx = getContext();
                                    Log.e(TAG, ctx.getString(
                                            R.string.msgs_cant_create_console), e);
                                    DialogHelper.showToast(ctx,
                                            R.string.msgs_cant_create_console,
                                            Toast.LENGTH_LONG);
                                    ((Activity)ctx).finish();
                                }
                            });
                            return null;

                        } catch (Exception ex) {
                            //End of loading data
                            if (NavigationView.this.mBreadcrumb != null) {
                                try {
                                    NavigationView.this.mBreadcrumb.endLoading();
                                } catch (Throwable ex2) {
                                    /**NON BLOCK**/
                                }
                            }

                            //Capture exception (attach task, and use listener to do the anim)
                            ExceptionUtil.attachAsyncTask(
                                ex,
                                new AsyncTask<Object, Integer, Boolean>() {
                                    private List<FileSystemObject> mTaskFiles = null;
                                    @Override
                                    @SuppressWarnings({
                                            "unchecked", "unqualified-field-access"
                                    })
                                    protected Boolean doInBackground(Object... taskParams) {
                                        mTaskFiles = (List<FileSystemObject>)taskParams[0];
                                        return Boolean.TRUE;
                                    }

                                    @Override
                                    @SuppressWarnings("unqualified-field-access")
                                    protected void onPostExecute(Boolean result) {
                                        if (!result.booleanValue()) {
                                            return;
                                        }
                                        onPostExecuteTask(
                                                mTaskFiles, addToHistory,
                                                isNewHistory, hasChanged,
                                                searchInfo, fNewDir, scrollTo);
                                    }
                                });
                            final OnRelaunchCommandResult exListener =
                                    new OnRelaunchCommandResult() {
                                @Override
                                public void onSuccess() {
                                    done();
                                }
                                @Override
                                public void onFailed(Throwable cause) {
                                    done();
                                }
                                @Override
                                public void onCancelled() {
                                    done();
                                }
                                private void done() {
                                    // Do animation
                                    fadeEfect(false);
                                    synchronized (mSync) {
                                        mChangingDir = false;
                                        mSync.notify();
                                    }
                                }
                            };
                            ExceptionUtil.translateException(
                                    getContext(), ex, false, true, exListener);
                        }
                        return null;
                    }

                    /**
                     * {@inheritDoc}
                     */
                    @Override
                    protected void onPreExecute() {
                        // Do animation
                        fadeEfect(true);
                    }

                    /**
                     * {@inheritDoc}
                     */
                    @Override
                    protected void onPostExecute(List<FileSystemObject> files) {
                        // This means an exception. This method will be recalled then
                        if (files != null) {
                            onPostExecuteTask(
                                    files, addToHistory, isNewHistory,
                                    hasChanged, searchInfo, fNewDir, scrollTo);

                            // Do animation
                            fadeEfect(false);

                            synchronized (mSync) {
                                mChangingDir = false;
                                mSync.notify();
                            }
                        }
                    }

                    /**
                     * Method that performs a fade animation.
                     *
                     * @param out Fade out (true); Fade in (false)
                     */
                    void fadeEfect(final boolean out) {
                        Activity activity = (Activity)getContext();
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Animation fadeAnim = out ?
                                        new AlphaAnimation(1, 0) :
                                        new AlphaAnimation(0, 1);
                                fadeAnim.setDuration(50L);
                                fadeAnim.setFillAfter(true);
                                fadeAnim.setInterpolator(new AccelerateInterpolator());
                                NavigationView.this.startAnimation(fadeAnim);
                            }
                        });
                    }
               };
        task.execute(fNewDir);
        NavigationTask task = new NavigationTask(useCurrent, addToHistory, reload,
                searchInfo, scrollTo);
        task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, newDir);
    }