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

Commit f5b8671c authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #5714517: App shortcuts can result in bad task intents

New API to let you build an Intent whose base configuration is correct,
but has an additional "selector" to pick out the specific app that you
would like launched.

Change-Id: Ide9db6dc60e2844b7696cfe09b28337fe7dd63db
parent 003c15d7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -5334,6 +5334,7 @@ package android.content {
    method public java.util.ArrayList<T> getParcelableArrayListExtra(java.lang.String);
    method public T getParcelableExtra(java.lang.String);
    method public java.lang.String getScheme();
    method public android.content.Intent getSelector();
    method public java.io.Serializable getSerializableExtra(java.lang.String);
    method public short[] getShortArrayExtra(java.lang.String);
    method public short getShortExtra(java.lang.String, short);
@@ -5346,6 +5347,7 @@ package android.content {
    method public boolean hasExtra(java.lang.String);
    method public boolean hasFileDescriptors();
    method public static android.content.Intent makeMainActivity(android.content.ComponentName);
    method public static android.content.Intent makeMainSelectorActivity(java.lang.String, java.lang.String);
    method public static android.content.Intent makeRestartActivityTask(android.content.ComponentName);
    method public static android.content.Intent parseIntent(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
    method public static android.content.Intent parseUri(java.lang.String, int) throws java.net.URISyntaxException;
@@ -5399,6 +5401,7 @@ package android.content {
    method public void setExtrasClassLoader(java.lang.ClassLoader);
    method public android.content.Intent setFlags(int);
    method public android.content.Intent setPackage(java.lang.String);
    method public void setSelector(android.content.Intent);
    method public void setSourceBounds(android.graphics.Rect);
    method public android.content.Intent setType(java.lang.String);
    method public deprecated java.lang.String toURI();
@@ -5577,6 +5580,7 @@ package android.content {
    field public static final int FILL_IN_COMPONENT = 8; // 0x8
    field public static final int FILL_IN_DATA = 2; // 0x2
    field public static final int FILL_IN_PACKAGE = 16; // 0x10
    field public static final int FILL_IN_SELECTOR = 64; // 0x40
    field public static final int FILL_IN_SOURCE_BOUNDS = 32; // 0x20
    field public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 4194304; // 0x400000
    field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
+68 −29
Original line number Diff line number Diff line
@@ -131,6 +131,10 @@ public class Am {
            runScreenCompat();
        } else if (op.equals("display-size")) {
            runDisplaySize();
        } else if (op.equals("to-uri")) {
            runToUri(false);
        } else if (op.equals("to-intent-uri")) {
            runToUri(true);
        } else {
            throw new IllegalArgumentException("Unknown command: " + op);
        }
@@ -138,6 +142,7 @@ public class Am {

    private Intent makeIntent() throws URISyntaxException {
        Intent intent = new Intent();
        Intent baseIntent = intent;
        boolean hasIntentInfo = false;

        mDebugOption = false;
@@ -152,35 +157,39 @@ public class Am {
        while ((opt=nextOption()) != null) {
            if (opt.equals("-a")) {
                intent.setAction(nextArgRequired());
                if (intent == baseIntent) {
                    hasIntentInfo = true;
                }
            } else if (opt.equals("-d")) {
                data = Uri.parse(nextArgRequired());
                if (intent == baseIntent) {
                    hasIntentInfo = true;
                }
            } else if (opt.equals("-t")) {
                type = nextArgRequired();
                if (intent == baseIntent) {
                    hasIntentInfo = true;
                }
            } else if (opt.equals("-c")) {
                intent.addCategory(nextArgRequired());
                if (intent == baseIntent) {
                    hasIntentInfo = true;
                }
            } else if (opt.equals("-e") || opt.equals("--es")) {
                String key = nextArgRequired();
                String value = nextArgRequired();
                intent.putExtra(key, value);
                hasIntentInfo = true;
            } else if (opt.equals("--esn")) {
                String key = nextArgRequired();
                intent.putExtra(key, (String) null);
                hasIntentInfo = true;
            } else if (opt.equals("--ei")) {
                String key = nextArgRequired();
                String value = nextArgRequired();
                intent.putExtra(key, Integer.valueOf(value));
                hasIntentInfo = true;
            } else if (opt.equals("--eu")) {
                String key = nextArgRequired();
                String value = nextArgRequired();
                intent.putExtra(key, Uri.parse(value));
                hasIntentInfo = true;
            } else if (opt.equals("--eia")) {
                String key = nextArgRequired();
                String value = nextArgRequired();
@@ -190,12 +199,10 @@ public class Am {
                    list[i] = Integer.valueOf(strings[i]);
                }
                intent.putExtra(key, list);
                hasIntentInfo = true;
            } else if (opt.equals("--el")) {
                String key = nextArgRequired();
                String value = nextArgRequired();
                intent.putExtra(key, Long.valueOf(value));
                hasIntentInfo = true;
            } else if (opt.equals("--ela")) {
                String key = nextArgRequired();
                String value = nextArgRequired();
@@ -205,18 +212,18 @@ public class Am {
                    list[i] = Long.valueOf(strings[i]);
                }
                intent.putExtra(key, list);
                hasIntentInfo = true;
            } else if (opt.equals("--ez")) {
                String key = nextArgRequired();
                String value = nextArgRequired();
                intent.putExtra(key, Boolean.valueOf(value));
                hasIntentInfo = true;
            } else if (opt.equals("-n")) {
                String str = nextArgRequired();
                ComponentName cn = ComponentName.unflattenFromString(str);
                if (cn == null) throw new IllegalArgumentException("Bad component name: " + str);
                intent.setComponent(cn);
                if (intent == baseIntent) {
                    hasIntentInfo = true;
                }
            } else if (opt.equals("-f")) {
                String str = nextArgRequired();
                intent.setFlags(Integer.decode(str).intValue());
@@ -264,6 +271,9 @@ public class Am {
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
            } else if (opt.equals("--receiver-replace-pending")) {
                intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
            } else if (opt.equals("--selector")) {
                intent.setDataAndType(data, type);
                intent = new Intent();
            } else if (opt.equals("-D")) {
                mDebugOption = true;
            } else if (opt.equals("-W")) {
@@ -286,10 +296,26 @@ public class Am {
        }
        intent.setDataAndType(data, type);

        final boolean hasSelector = intent != baseIntent;
        if (hasSelector) {
            // A selector was specified; fix up.
            baseIntent.setSelector(intent);
            intent = baseIntent;
        }

        String arg = nextArg();
        if (arg != null) {
            Intent baseIntent;
            if (arg.indexOf(':') >= 0) {
        baseIntent = null;
        if (arg == null) {
            if (hasSelector) {
                // If a selector has been specified, and no arguments
                // have been supplied for the main Intent, then we can
                // assume it is ACTION_MAIN CATEGORY_LAUNCHER; we don't
                // need to have a component name specified yet, the
                // selector will take care of that.
                baseIntent = new Intent(Intent.ACTION_MAIN);
                baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            }
        } else if (arg.indexOf(':') >= 0) {
            // The argument is a URI.  Fully parse it, and use that result
            // to fill in any data not specified so far.
            baseIntent = Intent.parseUri(arg, Intent.URI_INTENT_SCHEME);
@@ -305,6 +331,7 @@ public class Am {
            baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            baseIntent.setPackage(arg);
        }
        if (baseIntent != null) {
            Bundle extras = intent.getExtras();
            intent.replaceExtras((Bundle)null);
            Bundle uriExtras = baseIntent.getExtras();
@@ -315,7 +342,7 @@ public class Am {
                    baseIntent.removeCategory(c);
                }
            }
            intent.fillIn(baseIntent, Intent.FILL_IN_COMPONENT);
            intent.fillIn(baseIntent, Intent.FILL_IN_COMPONENT | Intent.FILL_IN_SELECTOR);
            if (extras == null) {
                extras = uriExtras;
            } else if (uriExtras != null) {
@@ -1064,6 +1091,11 @@ public class Am {
        }
    }

    private void runToUri(boolean intentScheme) throws Exception {
        Intent intent = makeIntent();
        System.out.println(intent.toUri(intentScheme ? Intent.URI_INTENT_SCHEME : 0));
    }

    private class IntentReceiver extends IIntentReceiver.Stub {
        private boolean mFinished = false;

@@ -1233,6 +1265,8 @@ public class Am {
                "       am monitor [--gdb <port>]\n" +
                "       am screen-compat [on|off] <PACKAGE>\n" +
                "       am display-size [reset|MxN]\n" +
                "       am to-uri [INTENT]\n" +
                "       am to-intent-uri [INTENT]\n" +
                "\n" +
                "am start: start an Activity.  Options are:\n" +
                "    -D: enable debugging\n" +
@@ -1284,6 +1318,10 @@ public class Am {
                "\n" +
                "am display-size: override display size.\n" +
                "\n" +
                "am to-uri: print the given Intent specification as a URI.\n" +
                "\n" +
                "am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
                "\n" +
                "<INTENT> specifications include these flags and arguments:\n" +
                "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
                "    [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
@@ -1308,6 +1346,7 @@ public class Am {
                "    [--activity-single-top] [--activity-clear-task]\n" +
                "    [--activity-task-on-home]\n" +
                "    [--receiver-registered-only] [--receiver-replace-pending]\n" +
                "    [--selector]\n" +
                "    [<URI> | <PACKAGE> | <COMPONENT>]\n"
                );
    }
+215 −14

File changed.

Preview size limit exceeded, changes collapsed.

+1 −2
Original line number Diff line number Diff line
@@ -1151,8 +1151,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
                    intent.setComponent(cn);
                    title = info.loadLabel(packageManager).toString();
                } else if (category != null) {
                    intent = new Intent(Intent.ACTION_MAIN, null);
                    intent.addCategory(category);
                    intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
                    title = "";
                } else {
                    Log.w(TAG, "Unable to add bookmark for shortcut " + shortcutStr
+1 −2
Original line number Diff line number Diff line
@@ -1638,8 +1638,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        if (down && repeatCount == 0) {
            String category = sApplicationLaunchKeyCategories.get(keyCode);
            if (category != null) {
                Intent intent = new Intent(Intent.ACTION_MAIN);
                intent.addCategory(category);
                Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                try {
                    mContext.startActivity(intent);
Loading