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

Commit 312d0ec5 authored by herriojr's avatar herriojr Committed by Jon Herriott
Browse files

Use System Resolver

Converting to using the system resolver.  The logic has changed slightly
in the following cases:

Open -- Tries to start activity, falls back to EditorActivity on failure
Open With -- Uses Chooser and populates Editor if not already there
	     Falls back to EditorActivity on failure
Click on FSObject -- Same as Open
Sending Object -- Same as Open

Cleaned up code around this a little since there were unused parameters.

Note: The Chooser will only show EXTRA_INITIAL_INTENTS if there are
other options as well, which is why we have to do the check up front
to see if we need to add it, and falling back to just using the Editor
if nothing exists to handle it.

Issue-Id: CYNGNOS-1236
Change-Id: I803b86cf6bfec80bbc886025be43ce800afd3be1
(cherry picked from commit 3a4d70fe)
parent 6bdd8e6c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1397,7 +1397,7 @@ public class SearchActivity extends Activity

            // Open the file here, so when focus back to the app, the search activity
            // its in top of the stack
            IntentsActionPolicy.openFileSystemObject(this, fso, false, null, null);
            IntentsActionPolicy.openFileSystemObject(this, fso, false, null);
        } else {
            // The fso not exists, delete the fso from the search
            try {
+1 −1
Original line number Diff line number Diff line
@@ -189,7 +189,7 @@ public class ShortcutActivity extends Activity implements OnCancelListener, OnDi

            } else {
                // Open the file. Delegate in action policy
                IntentsActionPolicy.openFileSystemObject(this, fso, false, this, this);
                IntentsActionPolicy.openFileSystemObject(this, fso, false, this);
            }

        } catch (Exception e) {
+5 −5
Original line number Diff line number Diff line
@@ -287,12 +287,12 @@ public class ActionsDialog implements OnItemClickListener, OnItemLongClickListen
            //- Open
            case R.id.mnu_actions_open:
                IntentsActionPolicy.openFileSystemObject(
                        this.mContext, this.mFso, false, null, null);
                        this.mContext, this.mFso, false, null);
                break;
            //- Open with
            case R.id.mnu_actions_open_with:
                IntentsActionPolicy.openFileSystemObject(
                        this.mContext, this.mFso, true, null, null);
                        this.mContext, this.mFso, true, null);
                break;

            //- Execute
@@ -303,7 +303,7 @@ public class ActionsDialog implements OnItemClickListener, OnItemLongClickListen
            //- Send
            case R.id.mnu_actions_send:
                IntentsActionPolicy.sendFileSystemObject(
                        this.mContext, this.mFso, null, null);
                        this.mContext, this.mFso, null);
                break;
            case R.id.mnu_actions_send_selection:
                if (this.mOnSelectionListener != null) {
@@ -311,10 +311,10 @@ public class ActionsDialog implements OnItemClickListener, OnItemLongClickListen
                            this.mOnSelectionListener.onRequestSelectedFiles();
                    if (selection.size() == 1) {
                        IntentsActionPolicy.sendFileSystemObject(
                                this.mContext, selection.get(0), null, null);
                                this.mContext, selection.get(0), null);
                    } else {
                        IntentsActionPolicy.sendMultipleFileSystemObject(
                                this.mContext, selection, null, null);
                                this.mContext, selection, null);
                    }
                }
                break;
+65 −189
Original line number Diff line number Diff line
@@ -19,18 +19,17 @@ package com.cyanogenmod.filemanager.ui.policy;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.activities.EditorActivity;
import com.cyanogenmod.filemanager.activities.ShortcutActivity;
import com.cyanogenmod.filemanager.console.secure.SecureConsole;
import com.cyanogenmod.filemanager.model.FileSystemObject;
@@ -40,7 +39,6 @@ import com.cyanogenmod.filemanager.providers.SecureResourceProvider.Authorizatio
import com.cyanogenmod.filemanager.providers.secure.ISecureChoiceCompleteListener;
import com.cyanogenmod.filemanager.providers.secure.SecureCacheCleanupService;
import com.cyanogenmod.filemanager.providers.secure.SecureChoiceClickListener;
import com.cyanogenmod.filemanager.ui.dialogs.AssociationsDialog;
import com.cyanogenmod.filemanager.util.DialogHelper;
import com.cyanogenmod.filemanager.util.ExceptionUtil;
import com.cyanogenmod.filemanager.util.FileHelper;
@@ -97,12 +95,11 @@ public final class IntentsActionPolicy extends ActionsPolicy {
     * @param ctx The current context
     * @param fso The file system object
     * @param choose If allow the user to select the application to open with
     * @param onCancelListener The cancel listener
     * @param onDismissListener The dismiss listener
     */
    public static void openFileSystemObject(
            final Context ctx, final FileSystemObject fso, final boolean choose,
            final OnCancelListener onCancelListener, final OnDismissListener onDismissListener) {
            final OnDismissListener onDismissListener) {
        try {
            // Create the intent to open the file
            final Intent intent = new Intent();
@@ -145,12 +142,6 @@ public final class IntentsActionPolicy extends ActionsPolicy {
                                                ctx,
                                                intent,
                                                choose,
                                                createInternalIntents(ctx, cacheFso),
                                                0,
                                                R.string.associations_dialog_openwith_title,
                                                R.string.associations_dialog_openwith_action,
                                                true,
                                                onCancelListener,
                                                onDismissListener);
                                    }

@@ -174,33 +165,28 @@ public final class IntentsActionPolicy extends ActionsPolicy {
            }

            // Resolve the intent
            resolveIntent(
                    ctx,
                    intent,
                    choose,
                    createInternalIntents(ctx, fso),
                    0,
                    R.string.associations_dialog_openwith_title,
                    R.string.associations_dialog_openwith_action,
                    true, onCancelListener, onDismissListener);

            resolveIntent(ctx, intent, choose, onDismissListener);
        } catch (Exception e) {
            ExceptionUtil.translateException(ctx, e);
        }
    }

    private static boolean handledByEditorInManifest(Context context, Intent intent) {
        Intent i = new Intent(intent);
        i.setPackage(context.getPackageName());
        return context.getPackageManager().queryIntentActivities(i, 0).size() > 0;
    }

    /**
     * Method that sends a {@link FileSystemObject} with the default registered application
     * by the system, or ask the user for select a registered application.
     *
     * @param ctx The current context
     * @param fso The file system object
     * @param onCancelListener The cancel listener
     * @param onDismissListener The dismiss listener
     */
    public static void sendFileSystemObject(
            final Context ctx, final FileSystemObject fso,
            OnCancelListener onCancelListener, OnDismissListener onDismissListener) {
            final Context ctx, final FileSystemObject fso, OnDismissListener onDismissListener) {
        try {
            // Create the intent to
            Intent intent = new Intent();
@@ -214,12 +200,8 @@ public final class IntentsActionPolicy extends ActionsPolicy {
            resolveIntent(
                    ctx,
                    intent,
                    true,
                    null,
                    0,
                    R.string.associations_dialog_sendwith_title,
                    R.string.associations_dialog_sendwith_action,
                    false, onCancelListener, onDismissListener);
                    false,
                    onDismissListener);

        } catch (Exception e) {
            ExceptionUtil.translateException(ctx, e);
@@ -232,12 +214,11 @@ public final class IntentsActionPolicy extends ActionsPolicy {
     *
     * @param ctx The current context
     * @param fsos The file system objects
     * @param onCancelListener The cancel listener
     * @param onDismissListener The dismiss listener
     */
    public static void sendMultipleFileSystemObject(
            final Context ctx, final List<FileSystemObject> fsos,
            OnCancelListener onCancelListener, OnDismissListener onDismissListener) {
            OnDismissListener onDismissListener) {
        try {
            // Create the intent to
            Intent intent = new Intent();
@@ -281,12 +262,8 @@ public final class IntentsActionPolicy extends ActionsPolicy {
            resolveIntent(
                    ctx,
                    intent,
                    true,
                    null,
                    0,
                    R.string.associations_dialog_sendwith_title,
                    R.string.associations_dialog_sendwith_action,
                    false, onCancelListener, onDismissListener);
                    false,
                    onDismissListener);

        } catch (Exception e) {
            ExceptionUtil.translateException(ctx, e);
@@ -298,170 +275,58 @@ public final class IntentsActionPolicy extends ActionsPolicy {
     *
     * @param ctx The current context
     * @param intent The intent to resolve
     * @param choose If allow the user to select the application to select the registered
     * application. If no preferred app or more than one exists the dialog is shown.
     * @param internals The list of internals intents that can handle the action
     * @param icon The icon of the dialog
     * @param title The title of the dialog
     * @param action The button title of the dialog
     * @param allowPreferred If allow the user to mark the selected app as preferred
     * @param onCancelListener The cancel listener
     * @param onDismissListener The dismiss listener
     */
    private static void resolveIntent(
            Context ctx, Intent intent, boolean choose, List<Intent> internals,
            int icon, int title, int action, boolean allowPreferred,
            OnCancelListener onCancelListener, OnDismissListener onDismissListener) {
        //Retrieve the activities that can handle the file
        final PackageManager packageManager = ctx.getPackageManager();
        if (DEBUG) {
            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
        }
        List<ResolveInfo> info =
                packageManager.
                    queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        Collections.sort(info, new Comparator<ResolveInfo>() {
            @Override
            public int compare(ResolveInfo lhs, ResolveInfo rhs) {
                boolean isLshCMFM =
                        lhs.activityInfo.packageName.compareTo(PREFERRED_PACKAGE) == 0;
                boolean isRshCMFM =
                        rhs.activityInfo.packageName.compareTo(PREFERRED_PACKAGE) == 0;
                if (isLshCMFM && !isRshCMFM) {
                    return -1;
                }
                if (!isLshCMFM && isRshCMFM) {
                    return 1;
                }
                return lhs.activityInfo.name.compareTo(rhs.activityInfo.name);
            }
            Context ctx, Intent intent, boolean choose, OnDismissListener onDismissListener) {
        if (choose) {
            PackageManager pm = ctx.getPackageManager();
            List<ResolveInfo> infos = pm.queryIntentActivities(intent, 0);

            Intent editor = new Intent(intent);
            editor.setClass(ctx, EditorActivity.class);

            if (infos.size() > 0) {
                // Try to only show the chooser when we have multiple items
                Intent i = Intent.createChooser(intent,
                        ctx.getString(R.string.associations_dialog_openwith_title));
                if (!handledByEditorInManifest(ctx, intent)) {
                    i.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{
                            editor,
                    });

        if (info.size() == 0) {
            // This basically checks the system to see if it possibly wants to handle it
            ResolveInfo ri = packageManager.resolveActivity(intent, 0);
            if (ri != null) {
                try {
                    ctx.startActivity(getIntentFromResolveInfo(ri, intent));
                    if (onDismissListener != null) {
                        onDismissListener.onDismiss(null);
                }
                    return;
                try {
                    ctx.startActivity(i);
                } catch (ActivityNotFoundException e) {
                    // fall through, we may still want to handle it with an internal activity
                }
            }
        }

        // Add the internal editors
        int count = 0;
        if (internals != null) {
            int cc = internals.size();
            for (int i = 0; i < cc; i++) {
                Intent ii = internals.get(i);
                List<ResolveInfo> ie =
                        packageManager.
                            queryIntentActivities(ii, 0);
                if (ie.size() > 0) {
                    ResolveInfo rie = ie.get(0);

                    // Only if the internal is not in the query list
                    boolean exists = false;
                    int ccc = info.size();
                    for (int j = 0; j < ccc; j++) {
                        ResolveInfo ri = info.get(j);
                        if (ri.activityInfo.packageName.compareTo(
                                rie.activityInfo.packageName) == 0 &&
                            ri.activityInfo.name.compareTo(
                                    rie.activityInfo.name) == 0) {

                            // Mark as internal
                            if (ri.activityInfo.metaData == null) {
                                ri.activityInfo.metaData = new Bundle();
                                ri.activityInfo.metaData.putString(
                                        EXTRA_INTERNAL_ACTION, ii.getAction());
                                ri.activityInfo.metaData.putBoolean(
                                        CATEGORY_INTERNAL_VIEWER, true);
                            }
                            exists = true;
                            break;
                        }
                    }
                    if (exists) {
                        continue;
                    }

                    // Mark as internal
                    if (rie.activityInfo.metaData == null) {
                        rie.activityInfo.metaData = new Bundle();
                        rie.activityInfo.metaData.putString(EXTRA_INTERNAL_ACTION, ii.getAction());
                        rie.activityInfo.metaData.putBoolean(CATEGORY_INTERNAL_VIEWER, true);
                    }

                    // Only one result must be matched
                    info.add(count, rie);
                    count++;
                }
            }
        }

        // No registered application
        if (info.size() == 0) {
            DialogHelper.showToast(ctx, R.string.msgs_not_registered_app, Toast.LENGTH_SHORT);
            if (onDismissListener != null) {
                onDismissListener.onDismiss(null);
                    try {
                        ctx.startActivity(editor);
                    } catch (ActivityNotFoundException e1) {
                        // Do nothing, this should never happen
                    }
            return;
                }

        // Retrieve the preferred activity that can handle the file. We only want the
        // resolved activity if the activity is a preferred activity. Other case, the
        // resolved activity was never added by addPreferredActivity
        ResolveInfo mPreferredInfo = findPreferredActivity(ctx, intent, info);

        // Is a simple open and we have an application that can handle the file?
        //---
        // If we have a preferred application, then use it
        if (!choose && (mPreferredInfo  != null && mPreferredInfo.match != 0)) {
            } else {
                try {
                ctx.startActivity(getIntentFromResolveInfo(mPreferredInfo, intent));
                if (onDismissListener != null) {
                    onDismissListener.onDismiss(null);
                }
                return;
                    ctx.startActivity(editor);
                } catch (ActivityNotFoundException e) {
                // fall through, the preferred may have been uninstalled.
                    // Do nothing, this should never happen
                }
            }
        // If there are only one activity (app or internal editor), then use it
        if (!choose && info.size() == 1) {
            ResolveInfo ri = info.get(0);
        } else {
            try {
                ctx.startActivity(getIntentFromResolveInfo(ri, intent));
                ctx.startActivity(intent);
            } catch (ActivityNotFoundException e) {
                DialogHelper.showToast(ctx, R.string.msgs_not_registered_app, Toast.LENGTH_SHORT);
                intent.setClass(ctx, EditorActivity.class);
                try {
                    ctx.startActivity(intent);
                } catch (ActivityNotFoundException e2) {
                    // This should never happen unless the editor is removed.
                }
            }
        }
        if (onDismissListener != null) {
            onDismissListener.onDismiss(null);
        }
            return;
        }

        // If we have multiples apps and there is not a preferred application then show
        // open with dialog
        AssociationsDialog dialog =
                new AssociationsDialog(
                        ctx,
                        icon,
                        ctx.getString(title),
                        ctx.getString(action),
                        intent,
                        info,
                        mPreferredInfo,
                        allowPreferred,
                        onCancelListener,
                        onDismissListener);
        dialog.show();
    }

    /**
@@ -519,7 +384,7 @@ public final class IntentsActionPolicy extends ActionsPolicy {
     */
    private static List<Intent> createInternalIntents(Context ctx, FileSystemObject fso) {
        List<Intent> intents = new ArrayList<Intent>();
        intents.addAll(createEditorIntent(ctx, fso));
        intents.addAll(createEditorIntents(ctx, fso));
        return intents;
    }

@@ -529,7 +394,7 @@ public final class IntentsActionPolicy extends ActionsPolicy {
     * @param ctx The current context
     * @param fso FileSystemObject
     */
    private static List<Intent> createEditorIntent(Context ctx, FileSystemObject fso) {
    private static List<Intent> createEditorIntents(Context ctx, FileSystemObject fso) {
        List<Intent> intents = new ArrayList<Intent>();
        MimeTypeCategory category = MimeTypeHelper.getCategory(ctx, fso);

@@ -549,6 +414,17 @@ public final class IntentsActionPolicy extends ActionsPolicy {
        return intents;
    }

    private static Intent createEditorIntent(Context ctx, FileSystemObject fso) {
        Intent editorIntent = null;
        MimeTypeCategory category = MimeTypeHelper.getCategory(ctx, fso);

        editorIntent = new Intent();
        editorIntent.setAction(Intent.ACTION_VIEW);
        editorIntent.addCategory(CATEGORY_INTERNAL_VIEWER);
        editorIntent.addCategory(CATEGORY_EDITOR);
        return editorIntent;
    }

    /**
     * Method that returns an {@link Intent} from his {@link ResolveInfo}
     *
+2 −2
Original line number Diff line number Diff line
@@ -1216,7 +1216,7 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
            changeCurrentDir(fso.getFullPath(), searchInfo);
        } else {
            // Open the file with the preferred registered app
            IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null, null);
            IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null);
        }
    }

@@ -1248,7 +1248,7 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
            // Open the file (edit or pick)
            if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
                // Open the file with the preferred registered app
                IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null, null);
                IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null);
            } else {
                // Request a file pick selection
                if (this.mOnFilePickedListener != null) {