Skip to content

Commit

Permalink
Fix issue #5714517: App shortcuts can result in bad task intents
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Dianne Hackborn committed Dec 6, 2011
1 parent 003c15d commit f5b8671
Show file tree
Hide file tree
Showing 7 changed files with 323 additions and 50 deletions.
4 changes: 4 additions & 0 deletions api/current.txt
Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down
97 changes: 68 additions & 29 deletions cmds/am/src/com/android/commands/am/Am.java
Expand Up @@ -131,13 +131,18 @@ private void run(String[] args) throws Exception {
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);
}
}

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

mDebugOption = false;
Expand All @@ -152,35 +157,39 @@ private Intent makeIntent() throws URISyntaxException {
while ((opt=nextOption()) != null) {
if (opt.equals("-a")) {
intent.setAction(nextArgRequired());
hasIntentInfo = true;
if (intent == baseIntent) {
hasIntentInfo = true;
}
} else if (opt.equals("-d")) {
data = Uri.parse(nextArgRequired());
hasIntentInfo = true;
if (intent == baseIntent) {
hasIntentInfo = true;
}
} else if (opt.equals("-t")) {
type = nextArgRequired();
hasIntentInfo = true;
if (intent == baseIntent) {
hasIntentInfo = true;
}
} else if (opt.equals("-c")) {
intent.addCategory(nextArgRequired());
hasIntentInfo = true;
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();
Expand All @@ -190,12 +199,10 @@ private Intent makeIntent() throws URISyntaxException {
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();
Expand All @@ -205,18 +212,18 @@ private Intent makeIntent() throws URISyntaxException {
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);
hasIntentInfo = true;
if (intent == baseIntent) {
hasIntentInfo = true;
}
} else if (opt.equals("-f")) {
String str = nextArgRequired();
intent.setFlags(Integer.decode(str).intValue());
Expand Down Expand Up @@ -264,6 +271,9 @@ private Intent makeIntent() throws URISyntaxException {
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")) {
Expand All @@ -286,25 +296,42 @@ private Intent makeIntent() throws URISyntaxException {
}
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) {
// 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);
} else if (arg.indexOf('/') >= 0) {
// The argument is a component name. Build an Intent to launch
// it.
baseIntent = new Intent(Intent.ACTION_MAIN);
baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
baseIntent.setComponent(ComponentName.unflattenFromString(arg));
} else {
// Assume the argument is a package name.
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);
baseIntent.setPackage(arg);
}
} 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);
} else if (arg.indexOf('/') >= 0) {
// The argument is a component name. Build an Intent to launch
// it.
baseIntent = new Intent(Intent.ACTION_MAIN);
baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
baseIntent.setComponent(ComponentName.unflattenFromString(arg));
} else {
// Assume the argument is a package name.
baseIntent = new Intent(Intent.ACTION_MAIN);
baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
baseIntent.setPackage(arg);
}
if (baseIntent != null) {
Bundle extras = intent.getExtras();
intent.replaceExtras((Bundle)null);
Bundle uriExtras = baseIntent.getExtras();
Expand All @@ -315,7 +342,7 @@ private Intent makeIntent() throws URISyntaxException {
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) {
Expand Down Expand Up @@ -1064,6 +1091,11 @@ private void runDisplaySize() throws Exception {
}
}

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;

Expand Down Expand Up @@ -1233,6 +1265,8 @@ private static void showUsage() {
" 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" +
Expand Down Expand Up @@ -1284,6 +1318,10 @@ private static void showUsage() {
"\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" +
Expand All @@ -1308,6 +1346,7 @@ private static void showUsage() {
" [--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"
);
}
Expand Down

0 comments on commit f5b8671

Please sign in to comment.