Skip to content

Commit 3b7d1ef

Browse files
committed
Migrate stream extras in CHOOSER intents.
When sending CHOOSER intent, inspect its target for any EXTRA_STREAM needing migration. If any migration happens, copy the ClipData to the CHOOSER intent and set GRANT_READ flag. Also update CHOOSER docs. Bug: 6463773 Change-Id: I66a7adf7bf6f2f173866925cb7e048f4c7a63222
1 parent 2411c33 commit 3b7d1ef

File tree

1 file changed

+44
-9
lines changed

1 file changed

+44
-9
lines changed

core/java/android/content/Intent.java

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -810,11 +810,17 @@ public String toString() {
810810
* <p>
811811
* As a convenience, an Intent of this form can be created with the
812812
* {@link #createChooser} function.
813-
* <p>Input: No data should be specified. get*Extra must have
813+
* <p>
814+
* If the target {@link #EXTRA_INTENT} contains {@link ClipData}, you should
815+
* also copy it to this intent along with relevant flags, such as
816+
* {@link #FLAG_GRANT_READ_URI_PERMISSION}.
817+
* <p>
818+
* Input: No data should be specified. get*Extra must have
814819
* a {@link #EXTRA_INTENT} field containing the Intent being executed,
815820
* and can optionally have a {@link #EXTRA_TITLE} field containing the
816821
* title text to display in the chooser.
817-
* <p>Output: Depends on the protocol of {@link #EXTRA_INTENT}.
822+
* <p>
823+
* Output: Depends on the protocol of {@link #EXTRA_INTENT}.
818824
*/
819825
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
820826
public static final String ACTION_CHOOSER = "android.intent.action.CHOOSER";
@@ -835,8 +841,17 @@ public static Intent createChooser(Intent target, CharSequence title) {
835841
if (title != null) {
836842
intent.putExtra(EXTRA_TITLE, title);
837843
}
844+
845+
// Migrate any clip data and flags from target.
846+
final ClipData targetClipData = target.getClipData();
847+
if (targetClipData != null) {
848+
intent.setClipData(targetClipData);
849+
intent.addFlags(target.getFlags()
850+
& (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION));
851+
}
838852
return intent;
839853
}
854+
840855
/**
841856
* Activity Action: Allow the user to select a particular kind of data and
842857
* return it. This is different than {@link #ACTION_PICK} in that here we
@@ -6587,19 +6602,35 @@ public static String normalizeMimeType(String type) {
65876602

65886603
/**
65896604
* Migrate any {@link #EXTRA_STREAM} in {@link #ACTION_SEND} and
6590-
* {@link #ACTION_SEND_MULTIPLE} to {@link ClipData}.
6605+
* {@link #ACTION_SEND_MULTIPLE} to {@link ClipData}. Also inspects nested
6606+
* intents in {@link #ACTION_CHOOSER}.
65916607
*
6608+
* @return Whether any contents were migrated.
65926609
* @hide
65936610
*/
6594-
public void migrateExtraStreamToClipData() {
6611+
public boolean migrateExtraStreamToClipData() {
65956612
// Refuse to touch if extras already parcelled
6596-
if (mExtras != null && mExtras.isParcelled()) return;
6613+
if (mExtras != null && mExtras.isParcelled()) return false;
65976614

65986615
// Bail when someone already gave us ClipData
6599-
if (getClipData() != null) return;
6616+
if (getClipData() != null) return false;
66006617

66016618
final String action = getAction();
6602-
if (ACTION_SEND.equals(action)) {
6619+
if (ACTION_CHOOSER.equals(action)) {
6620+
// Inspect target intent to see if we need to migrate
6621+
final Intent target = getParcelableExtra(EXTRA_INTENT);
6622+
if (target.migrateExtraStreamToClipData()) {
6623+
// Since we migrated in child, we need to promote ClipData and
6624+
// flags to ourselves to grant.
6625+
setClipData(target.getClipData());
6626+
addFlags(target.getFlags()
6627+
& (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION));
6628+
return true;
6629+
} else {
6630+
return false;
6631+
}
6632+
6633+
} else if (ACTION_SEND.equals(action)) {
66036634
try {
66046635
final Uri stream = getParcelableExtra(EXTRA_STREAM);
66056636
final CharSequence text = getCharSequenceExtra(EXTRA_TEXT);
@@ -6610,6 +6641,7 @@ public void migrateExtraStreamToClipData() {
66106641
new ClipData.Item(text, htmlText, null, stream));
66116642
setClipData(clipData);
66126643
addFlags(FLAG_GRANT_READ_URI_PERMISSION);
6644+
return true;
66136645
}
66146646
} catch (ClassCastException e) {
66156647
}
@@ -6626,14 +6658,14 @@ public void migrateExtraStreamToClipData() {
66266658
if (texts != null) {
66276659
if (num >= 0 && num != texts.size()) {
66286660
// Wha...! F- you.
6629-
return;
6661+
return false;
66306662
}
66316663
num = texts.size();
66326664
}
66336665
if (htmlTexts != null) {
66346666
if (num >= 0 && num != htmlTexts.size()) {
66356667
// Wha...! F- you.
6636-
return;
6668+
return false;
66376669
}
66386670
num = htmlTexts.size();
66396671
}
@@ -6648,10 +6680,13 @@ public void migrateExtraStreamToClipData() {
66486680

66496681
setClipData(clipData);
66506682
addFlags(FLAG_GRANT_READ_URI_PERMISSION);
6683+
return true;
66516684
}
66526685
} catch (ClassCastException e) {
66536686
}
66546687
}
6688+
6689+
return false;
66556690
}
66566691

66576692
private static ClipData.Item makeClipItem(ArrayList<Uri> streams, ArrayList<CharSequence> texts,

0 commit comments

Comments
 (0)