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

Commit 6d8dfbd8 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #10848916: "Always" button is not working.

The problem was that the ResolverActivity filters some activities
out of the list it shows, but it uses that display list as the
list of components the preference is set against when ultimately
setting it on the package manager...  but that filtered list is *not*
the right component set, since it is not the same as the package
manager's view on it.

The fix here is to retain the original set of matching components
and use that when setting the preferred activity.  Note that this
does mean that in very unusual cases where filtering is happeing
(such as one of the activities not being exported but being seen
as a possible completion from another app), then you will be setting
the preference for the complete set.  Ultimately we probably need
to have the package manager apply these filtering rules up-front so
this is all consistent, but this is a very rare case so not that
important.

And then most of the change here is just improving the debug
output for intent resolution.

Change-Id: Ie35ac2c05a45946439951bbf41433c8b7de79c05
parent cfdc0369
Loading
Loading
Loading
Loading
+50 −2
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package android.content;

import android.os.Parcel;
import android.os.Parcelable;

import java.io.PrintWriter;
import java.lang.Comparable;

/**
@@ -109,6 +111,32 @@ public final class ComponentName implements Parcelable, Cloneable, Comparable<Co
        return mClass;
    }
    
    private static void appendShortClassName(StringBuilder sb, String packageName,
            String className) {
        if (className.startsWith(packageName)) {
            int PN = packageName.length();
            int CN = className.length();
            if (CN > PN && className.charAt(PN) == '.') {
                sb.append(className, PN, CN);
                return;
            }
        }
        sb.append(className);
    }

    private static void printShortClassName(PrintWriter pw, String packageName,
            String className) {
        if (className.startsWith(packageName)) {
            int PN = packageName.length();
            int CN = className.length();
            if (CN > PN && className.charAt(PN) == '.') {
                pw.write(className, PN, CN-PN);
                return;
            }
        }
        pw.print(className);
    }

    /**
     * Return a String that unambiguously describes both the package and
     * class names contained in the ComponentName.  You can later recover
@@ -137,7 +165,27 @@ public final class ComponentName implements Parcelable, Cloneable, Comparable<Co
     * @see #unflattenFromString(String)
     */
    public String flattenToShortString() {
        return mPackage + "/" + getShortClassName();
        StringBuilder sb = new StringBuilder(mPackage.length() + mClass.length());
        appendShortString(sb, mPackage, mClass);
        return sb.toString();
    }

    /** @hide */
    public void appendShortString(StringBuilder sb) {
        appendShortString(sb, mPackage, mClass);
    }

    /** @hide */
    public static void appendShortString(StringBuilder sb, String packageName, String className) {
        sb.append(packageName).append('/');
        appendShortClassName(sb, packageName, className);
    }

    /** @hide */
    public static void printShortString(PrintWriter pw, String packageName, String className) {
        pw.print(packageName);
        pw.print('/');
        printShortClassName(pw, packageName, className);
    }

    /**
+51 −29
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
@@ -3708,15 +3709,12 @@ public class PackageParser {
            return componentName;
        }

        public String getComponentShortName() {
            if (componentShortName != null) {
                return componentShortName;
        public void appendComponentShortName(StringBuilder sb) {
            ComponentName.appendShortString(sb, owner.applicationInfo.packageName, className);
        }
            ComponentName component = getComponentName();
            if (component != null) {
                componentShortName = component.flattenToShortString();
            }
            return componentShortName;

        public void printComponentShortName(PrintWriter pw) {
            ComponentName.printShortString(pw, owner.applicationInfo.packageName, className);
        }

        public void setPackageName(String packageName) {
@@ -3917,9 +3915,13 @@ public class PackageParser {
        }

        public String toString() {
            return "Activity{"
                + Integer.toHexString(System.identityHashCode(this))
                + " " + getComponentShortName() + "}";
            StringBuilder sb = new StringBuilder(128);
            sb.append("Activity{");
            sb.append(Integer.toHexString(System.identityHashCode(this)));
            sb.append(' ');
            appendComponentShortName(sb);
            sb.append('}');
            return sb.toString();
        }
    }

@@ -3954,9 +3956,13 @@ public class PackageParser {
        }

        public String toString() {
            return "Service{"
                + Integer.toHexString(System.identityHashCode(this))
                + " " + getComponentShortName() + "}";
            StringBuilder sb = new StringBuilder(128);
            sb.append("Service{");
            sb.append(Integer.toHexString(System.identityHashCode(this)));
            sb.append(' ');
            appendComponentShortName(sb);
            sb.append('}');
            return sb.toString();
        }
    }

@@ -3999,9 +4005,13 @@ public class PackageParser {
        }

        public String toString() {
            return "Provider{"
                + Integer.toHexString(System.identityHashCode(this))
                + " " + info.name + "}";
            StringBuilder sb = new StringBuilder(128);
            sb.append("Provider{");
            sb.append(Integer.toHexString(System.identityHashCode(this)));
            sb.append(' ');
            appendComponentShortName(sb);
            sb.append('}');
            return sb.toString();
        }
    }

@@ -4040,9 +4050,13 @@ public class PackageParser {
        }

        public String toString() {
            return "Instrumentation{"
                + Integer.toHexString(System.identityHashCode(this))
                + " " + getComponentShortName() + "}";
            StringBuilder sb = new StringBuilder(128);
            sb.append("Instrumentation{");
            sb.append(Integer.toHexString(System.identityHashCode(this)));
            sb.append(' ');
            appendComponentShortName(sb);
            sb.append('}');
            return sb.toString();
        }
    }

@@ -4074,9 +4088,13 @@ public class PackageParser {
        }

        public String toString() {
            return "ActivityIntentInfo{"
                + Integer.toHexString(System.identityHashCode(this))
                + " " + activity.info.name + "}";
            StringBuilder sb = new StringBuilder(128);
            sb.append("ActivityIntentInfo{");
            sb.append(Integer.toHexString(System.identityHashCode(this)));
            sb.append(' ');
            activity.appendComponentShortName(sb);
            sb.append('}');
            return sb.toString();
        }
    }

@@ -4088,9 +4106,13 @@ public class PackageParser {
        }

        public String toString() {
            return "ServiceIntentInfo{"
                + Integer.toHexString(System.identityHashCode(this))
                + " " + service.info.name + "}";
            StringBuilder sb = new StringBuilder(128);
            sb.append("ServiceIntentInfo{");
            sb.append(Integer.toHexString(System.identityHashCode(this)));
            sb.append(' ');
            service.appendComponentShortName(sb);
            sb.append('}');
            return sb.toString();
        }
    }

+18 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.content.pm;

import android.content.ComponentName;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
@@ -247,10 +248,23 @@ public class ResolveInfo implements Parcelable {

    public String toString() {
        ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
        return "ResolveInfo{"
            + Integer.toHexString(System.identityHashCode(this))
            + " " + ci.name + " p=" + priority + " o="
            + preferredOrder + " m=0x" + Integer.toHexString(match) + "}";
        StringBuilder sb = new StringBuilder(128);
        sb.append("ResolveInfo{");
        sb.append(Integer.toHexString(System.identityHashCode(this)));
        sb.append(' ');
        ComponentName.appendShortString(sb, ci.packageName, ci.name);
        if (priority != 0) {
            sb.append(" p=");
            sb.append(priority);
        }
        if (preferredOrder != 0) {
            sb.append(" o=");
            sb.append(preferredOrder);
        }
        sb.append(" m=0x");
        sb.append(Integer.toHexString(match));
        sb.append('}');
        return sb.toString();
    }

    public int describeContents() {
+15 −8
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.LabeledIntent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -89,6 +88,7 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte

    private Intent makeMyIntent() {
        Intent intent = new Intent(getIntent());
        intent.setComponent(null);
        // The resolver activity is set to be hidden from recent tasks.
        // we don't want this attribute to be propagated to the next activity
        // being launched.  Note that if the original Intent also had this
@@ -119,7 +119,6 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
        mPm = getPackageManager();
        mAlwaysUseOption = alwaysUseOption;
        mMaxColumns = getResources().getInteger(R.integer.config_maxResolverActivityColumns);
        intent.setComponent(null);

        AlertController.AlertParams ap = mAlertParams;

@@ -290,7 +289,7 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
    }

    protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
        if (mAlwaysUseOption) {
        if (mAlwaysUseOption && mAdapter.mOrigResolveList != null) {
            // Build a reasonable intent filter, based on what matched.
            IntentFilter filter = new IntentFilter();

@@ -367,11 +366,11 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
            }

            if (filter != null) {
                final int N = mAdapter.mList.size();
                final int N = mAdapter.mOrigResolveList.size();
                ComponentName[] set = new ComponentName[N];
                int bestMatch = 0;
                for (int i=0; i<N; i++) {
                    ResolveInfo r = mAdapter.mList.get(i).ri;
                    ResolveInfo r = mAdapter.mOrigResolveList.get(i);
                    set[i] = new ComponentName(r.activityInfo.packageName,
                            r.activityInfo.name);
                    if (r.match > bestMatch) bestMatch = r.match;
@@ -428,13 +427,14 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
        private final int mLaunchedFromUid;
        private final LayoutInflater mInflater;

        private List<DisplayResolveInfo> mList;
        List<DisplayResolveInfo> mList;
        List<ResolveInfo> mOrigResolveList;

        private int mInitialHighlight = -1;

        public ResolveListAdapter(Context context, Intent intent,
                Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid) {
            mIntent = new Intent(intent);
            mIntent.setComponent(null);
            mInitialIntents = initialIntents;
            mBaseResolveList = rList;
            mLaunchedFromUid = launchedFromUid;
@@ -472,8 +472,9 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
            mList.clear();
            if (mBaseResolveList != null) {
                currentResolveList = mBaseResolveList;
                mOrigResolveList = null;
            } else {
                currentResolveList = mPm.queryIntentActivities(
                currentResolveList = mOrigResolveList = mPm.queryIntentActivities(
                        mIntent, PackageManager.MATCH_DEFAULT_ONLY
                        | (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0));
                // Filter out any activities that the launched uid does not
@@ -489,6 +490,9 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
                                ai.applicationInfo.uid, ai.exported);
                        if (granted != PackageManager.PERMISSION_GRANTED) {
                            // Access not allowed!
                            if (mOrigResolveList == currentResolveList) {
                                mOrigResolveList = new ArrayList<ResolveInfo>(mOrigResolveList);
                            }
                            currentResolveList.remove(i);
                        }
                    }
@@ -510,6 +514,9 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
                    if (r0.priority != ri.priority ||
                        r0.isDefault != ri.isDefault) {
                        while (i < N) {
                            if (mOrigResolveList == currentResolveList) {
                                mOrigResolveList = new ArrayList<ResolveInfo>(mOrigResolveList);
                            }
                            currentResolveList.remove(i);
                            N--;
                        }
+66 −5
Original line number Diff line number Diff line
package com.android.internal.util;

import android.util.Printer;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
@@ -41,6 +43,7 @@ public class FastPrintWriter extends PrintWriter {
    final private String mSeparator;

    final private Writer mWriter;
    final private Printer mPrinter;

    private CharsetEncoder mCharset;
    final private ByteBuffer mBytes;
@@ -106,6 +109,7 @@ public class FastPrintWriter extends PrintWriter {
        mBytes = ByteBuffer.allocate(mBufferLen);
        mOutputStream = out;
        mWriter = null;
        mPrinter = null;
        mAutoFlush = autoFlush;
        mSeparator = System.lineSeparator();
        initDefaultEncoder();
@@ -130,7 +134,7 @@ public class FastPrintWriter extends PrintWriter {
    }

    /**
     * Constructs a new {@code PrintWriter} with {@code out} as its target
     * Constructs a new {@code PrintWriter} with {@code wr} as its target
     * writer. The parameter {@code autoFlush} determines if the print writer
     * automatically flushes its contents to the target writer when a newline is
     * encountered.
@@ -148,7 +152,7 @@ public class FastPrintWriter extends PrintWriter {
    }

    /**
     * Constructs a new {@code PrintWriter} with {@code out} as its target
     * Constructs a new {@code PrintWriter} with {@code wr} as its target
     * writer and a custom buffer size. The parameter {@code autoFlush} determines
     * if the print writer automatically flushes its contents to the target writer
     * when a newline is encountered.
@@ -174,11 +178,55 @@ public class FastPrintWriter extends PrintWriter {
        mBytes = null;
        mOutputStream = null;
        mWriter = wr;
        mPrinter = null;
        mAutoFlush = autoFlush;
        mSeparator = System.lineSeparator();
        initDefaultEncoder();
    }

    /**
     * Constructs a new {@code PrintWriter} with {@code pr} as its target
     * printer and the default buffer size.  Because a {@link Printer} is line-base,
     * autoflush is always enabled.
     *
     * @param pr
     *            the target writer.
     * @throws NullPointerException
     *             if {@code pr} is {@code null}.
     */
    public FastPrintWriter(Printer pr) {
        this(pr, 512);
    }

    /**
     * Constructs a new {@code PrintWriter} with {@code pr} as its target
     * printer and a custom buffer size.  Because a {@link Printer} is line-base,
     * autoflush is always enabled.
     *
     * @param pr
     *            the target writer.
     * @param bufferLen
     *            specifies the size of the FastPrintWriter's internal buffer; the
     *            default is 512.
     * @throws NullPointerException
     *             if {@code pr} is {@code null}.
     */
    public FastPrintWriter(Printer pr, int bufferLen) {
        super(sDummyWriter, true);
        if (pr == null) {
            throw new NullPointerException("pr is null");
        }
        mBufferLen = bufferLen;
        mText = new char[bufferLen];
        mBytes = null;
        mOutputStream = null;
        mWriter = null;
        mPrinter = pr;
        mAutoFlush = true;
        mSeparator = System.lineSeparator();
        initDefaultEncoder();
    }

    private final void initEncoder(String csn) throws UnsupportedEncodingException {
        try {
            mCharset = Charset.forName(csn).newEncoder();
@@ -306,9 +354,22 @@ public class FastPrintWriter extends PrintWriter {
                }
                flushBytesLocked();
                mOutputStream.flush();
            } else {
            } else if (mWriter != null) {
                mWriter.write(mText, 0, mPos);
                mWriter.flush();
            } else {
                int nonEolOff = 0;
                final int sepLen = mSeparator.length();
                final int len = sepLen < mPos ? sepLen : mPos;
                while (nonEolOff < len && mText[mPos-1-nonEolOff]
                        == mSeparator.charAt(mSeparator.length()-1-nonEolOff)) {
                    nonEolOff++;
                }
                if (nonEolOff >= mPos) {
                    mPrinter.println("");
                } else {
                    mPrinter.println(new String(mText, 0, mPos-nonEolOff));
                }
            }
            mPos = 0;
        }
@@ -326,7 +387,7 @@ public class FastPrintWriter extends PrintWriter {
                flushLocked();
                if (mOutputStream != null) {
                    mOutputStream.flush();
                } else {
                } else if (mWriter != null) {
                    mWriter.flush();
                }
            } catch (IOException e) {
@@ -342,7 +403,7 @@ public class FastPrintWriter extends PrintWriter {
                flushLocked();
                if (mOutputStream != null) {
                    mOutputStream.close();
                } else {
                } else if (mWriter != null) {
                    mWriter.close();
                }
            } catch (IOException e) {
Loading