am a7c5791a: Merge "Redefine FLAG_ACTIVITY_NEW_DOCUMENT without NEW_TASK" into lmp-preview-dev

* commit 'a7c5791a95bf732c2381f698d78930ee61efd36b':
  Redefine FLAG_ACTIVITY_NEW_DOCUMENT without NEW_TASK
This commit is contained in:
Craig Mautner
2014-06-10 17:21:52 +00:00
committed by Android Git Automerger
6 changed files with 78 additions and 70 deletions

View File

@@ -7558,12 +7558,12 @@ package android.content {
field public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 4194304; // 0x400000
field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
field public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; // 0x4000000
field public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
field public static final deprecated int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
field public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; // 0x800000
field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
field public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; // 0x8000000
field public static final int FLAG_ACTIVITY_NEW_DOCUMENT = 268959744; // 0x10080000
field public static final int FLAG_ACTIVITY_NEW_DOCUMENT = 524288; // 0x80000
field public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; // 0x10000000
field public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536; // 0x10000
field public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824; // 0x40000000
@@ -8043,6 +8043,7 @@ package android.content.pm {
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int DOCUMENT_LAUNCH_ALWAYS = 2; // 0x2
field public static final int DOCUMENT_LAUNCH_INTO_EXISTING = 1; // 0x1
field public static final int DOCUMENT_LAUNCH_NEVER = 3; // 0x3
field public static final int DOCUMENT_LAUNCH_NONE = 0; // 0x0
field public static final int FLAG_ALLOW_TASK_REPARENTING = 64; // 0x40
field public static final int FLAG_ALWAYS_RETAIN_TASK_STATE = 8; // 0x8

View File

@@ -3711,30 +3711,8 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 0x00100000;
/**
* If set, this marks a point in the task's activity stack that should
* be cleared when the task is reset. That is, the next time the task
* is brought to the foreground with
* {@link #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED} (typically as a result of
* the user re-launching it from home), this activity and all on top of
* it will be finished so that the user does not return to them, but
* instead returns to whatever activity preceeded it.
*
* <p>When this flag is assigned to the root activity all activities up
* to, but not including the root activity, will be cleared. This prevents
* this flag from being used to finish all activities in a task and thereby
* ending the task.
*
* <p>This is useful for cases where you have a logical break in your
* application. For example, an e-mail application may have a command
* to view an attachment, which launches an image view activity to
* display it. This activity should be part of the e-mail application's
* task, since it is a part of the task the user is involved in. However,
* if the user leaves that task, and later selects the e-mail app from
* home, we may like them to return to the conversation they were
* viewing, not the picture attachment, since that is confusing. By
* setting this flag when launching the image viewer, that viewer and
* any activities it starts will be removed the next time the user returns
* to mail.
* @deprecated As of API 21 this performs identically to
* {@link #FLAG_ACTIVITY_NEW_DOCUMENT} which should be used instead of this.
*/
public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000;
/**
@@ -3761,8 +3739,7 @@ public class Intent implements Parcelable, Cloneable {
* @see android.R.attr#documentLaunchMode
* @see #FLAG_ACTIVITY_MULTIPLE_TASK
*/
public static final int FLAG_ACTIVITY_NEW_DOCUMENT =
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | FLAG_ACTIVITY_NEW_TASK;
public static final int FLAG_ACTIVITY_NEW_DOCUMENT = FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET;
/**
* If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaveHint}
* callback from occurring on the current frontmost activity before it is

View File

@@ -83,6 +83,11 @@ public class ActivityInfo extends ComponentInfo
* the {@link android.R.attr#documentLaunchMode} attribute.
*/
public static final int DOCUMENT_LAUNCH_ALWAYS = 2;
/**
* Constant corresponding to <code>never</code> in
* the {@link android.R.attr#documentLaunchMode} attribute.
*/
public static final int DOCUMENT_LAUNCH_NEVER = 3;
/**
* The document launch mode style requested by the activity. From the
* {@link android.R.attr#documentLaunchMode} attribute, one of

View File

@@ -898,16 +898,22 @@
android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} to every Intent used to launch
the activity.
<p>The documentLaunchMode attribute may be assigned one of three values, "none",
"intoExisting" and "always", described in detail below. For values other than
<code>none</code> the activity must be defined with
{@link android.R.attr#launchMode} <code>standard</code> or <code>singleTop</code>.
<p>The documentLaunchMode attribute may be assigned one of four values, "none",
"intoExisting", "always" and "never", described in detail below. For values other than
<code>none</code> and <code>never</code> the activity must be defined with
{@link android.R.attr#launchMode} <code>standard</code>.
If this attribute is not specified, <code>none</code> will be used.
Note that <code>none</code> can be overridden at run time if the Intent used
to launch it contains the flag {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}.
to launch it contains the flag {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT
Intent.FLAG_ACTIVITY_NEW_DOCUMENT}.
Similarly <code>intoExisting</code> will be overridden by the flag
{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} combined with
{@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}. -->
{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT
Intent.FLAG_ACTIVITY_NEW_DOCUMENT} combined with
{@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK
Intent.FLAG_ACTIVITY_MULTIPLE_TASK}. If the value of
documentLaunchModes is <code>never</code> then any use of
.........{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT
Intent.FLAG_ACTIVITY_NEW_DOCUMENT} to launch this activity will be ignored. -->
<attr name="documentLaunchMode">
<!-- The default mode, which will create a new task only when
{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK
@@ -931,6 +937,13 @@
and {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK
Intent.FLAG_ACTIVITY_MULTIPLE_TASK} both set. -->
<enum name="always" value="2" />
<!-- This activity will not be launched into a new document even if the Intent contains
{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT
Intent.FLAG_ACTIVITY_NEW_DOCUMENT}. This gives the activity writer ultimate
control over how their activity is used. Note that applications prior to api
21 will default to documentLaunchMode="none" so only activities that explicitly
opt out with <code>"never"</code> may do so. -->
<enum name="never" value="3" />
</attr>
<!-- The maximum number of entries of tasks rooted at this activity in the recent task list.

View File

@@ -1269,7 +1269,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
// to ensure that it is safe to do so. If the upcoming activity will also
// be part of the voice session, we can only launch it if it has explicitly
// said it supports the VOICE category, or it is a part of the calling app.
if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
try {
if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
@@ -1486,6 +1486,47 @@ public final class ActivityStackSupervisor implements DisplayListener {
int launchFlags = intent.getFlags();
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
(r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK)) {
// We have a conflict between the Intent and the Activity manifest, manifest wins.
Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
"\"singleInstance\" or \"singleTask\"");
launchFlags &=
~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
} else {
switch (r.info.documentLaunchMode) {
case ActivityInfo.DOCUMENT_LAUNCH_NONE:
break;
case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
break;
case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
break;
case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
break;
}
}
if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
// For whatever reason this activity is being launched into a new
// task... yet the caller has requested a result back. Well, that
// is pretty messed up, so instead immediately send back a cancel
// and let the new task continue launched as normal without a
// dependency on its originator.
Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
r.resultTo.task.stack.sendActivityResultLocked(-1,
r.resultTo, r.resultWho, r.requestCode,
Activity.RESULT_CANCELED, null);
r.resultTo = null;
}
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
}
// We'll invoke onUserLeaving before onPause only if the launching
// activity did not explicitly state that this is an automated launch.
mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
@@ -1516,20 +1557,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
}
switch (r.info.documentLaunchMode) {
case ActivityInfo.DOCUMENT_LAUNCH_NONE:
break;
case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
intent.addFlags(
Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
launchFlags = intent.getFlags();
break;
case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
launchFlags = intent.getFlags();
break;
}
final boolean newDocument = intent.isDocument();
if (sourceRecord == null) {
// This activity is not being started from another... in this
// case we -always- start a new task.
@@ -1538,11 +1565,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
"Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
}
} else if (newDocument) {
if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) {
Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\"");
r.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
}
} else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
// The original activity who is starting us is running as a single
// instance... this new activity it is starting must go on its
@@ -1581,18 +1603,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
sourceStack = null;
}
if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
// For whatever reason this activity is being launched into a new
// task... yet the caller has requested a result back. Well, that
// is pretty messed up, so instead immediately send back a cancel
// and let the new task continue launched as normal without a
// dependency on its originator.
Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
r.resultTo.task.stack.sendActivityResultLocked(-1,
r.resultTo, r.resultWho, r.requestCode,
Activity.RESULT_CANCELED, null);
r.resultTo = null;
}
intent.setFlags(launchFlags);
boolean addingToTask = false;
boolean movedHome = false;
@@ -1827,7 +1838,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
// Should this be considered a new task?
if (r.resultTo == null && !addingToTask
&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
&& (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
if (isLockTaskModeViolation(reuseTask)) {
Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;

View File

@@ -647,8 +647,9 @@ final class TaskRecord extends ThumbnailHolder {
final int numActivities = activities.size();
for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
if (!r.isPersistable() || (r.intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) {
if (!r.isPersistable() || (activityNdx > 0 &&
(r.intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0)) {
// Stop at first non-persistable or first break in task (CLEAR_WHEN_TASK_RESET).
break;
}
out.startTag(null, TAG_ACTIVITY);