Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6849,6 +6849,7 @@ package android.content { 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_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 core/java/android/content/Intent.java +52 −3 Original line number Diff line number Diff line Loading @@ -3457,7 +3457,16 @@ public class Intent implements Parcelable, Cloneable { */ public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000; /** * <strong>Do not use this flag unless you are implementing your own * This flag is used to create a new task and launch an activity into it. * This flag is always paired with either {@link #FLAG_ACTIVITY_NEW_DOCUMENT} * or {@link #FLAG_ACTIVITY_NEW_TASK}. In both cases these flags alone would * search through existing tasks for ones matching this Intent. Only if no such * task is found would a new task be created. When paired with * FLAG_ACTIVITY_MULTIPLE_TASK both of these behaviors are modified to skip * the search for a matching task and unconditionally start a new task. * * <strong>When used with {@link #FLAG_ACTIVITY_NEW_TASK} do not use this * flag unless you are implementing your own * top-level application launcher.</strong> Used in conjunction with * {@link #FLAG_ACTIVITY_NEW_TASK} to disable the * behavior of bringing an existing task to the foreground. When set, Loading @@ -3469,12 +3478,18 @@ public class Intent implements Parcelable, Cloneable { * you should not use this flag unless you provide some way for a user to * return back to the tasks you have launched.</strong> * * <p>This flag is ignored if * {@link #FLAG_ACTIVITY_NEW_TASK} is not set. * See {@link #FLAG_ACTIVITY_NEW_DOCUMENT} for details of this flag's use for * creating new document tasks. * * <p>This flag is ignored if one of {@link #FLAG_ACTIVITY_NEW_TASK} or * {@link #FLAG_ACTIVITY_NEW_TASK} is not also set. * * <p>See * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back * Stack</a> for more information about tasks. * * @see #FLAG_ACTIVITY_NEW_DOCUMENT * @see #FLAG_ACTIVITY_NEW_TASK */ public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000; /** Loading Loading @@ -3580,6 +3595,34 @@ public class Intent implements Parcelable, Cloneable { * to mail. */ public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000; /** * This flag is used to break out "documents" into separate tasks that can * be reached via the Recents mechanism. Such a document is any kind of * item for which an application may want to maintain multiple simultaneous * instances. Examples might be text files, web pages, spreadsheets, or * emails. Each such document will be in a separate task in the Recents list. * * <p>When set, the activity specified by this Intent will launch into a * separate task rooted at that activity. The activity launched must be * defined with {@link android.R.attr#launchMode} "standard" or "singleTop". * * <p>If FLAG_ACTIVITY_NEW_DOCUMENT is used without * {@link #FLAG_ACTIVITY_MULTIPLE_TASK} then the activity manager will * search for an existing task with a matching target activity and Intent * data URI and relaunch that task, first finishing all activities down to * the root activity and then calling the root activity's * {@link android.app.Activity#onNewIntent(Intent)} method. If no existing * task's root activity matches the Intent's data URI then a new task will * be launched with the target activity as root. * * <p>When paired with {@link #FLAG_ACTIVITY_MULTIPLE_TASK} this will * always create a new task. Thus the same document may be made to appear * more than one time in Recents. * * @see #FLAG_ACTIVITY_MULTIPLE_TASK */ public static final int FLAG_ACTIVITY_NEW_DOCUMENT = FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | FLAG_ACTIVITY_NEW_TASK; /** * If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaveHint} * callback from occurring on the current frontmost activity before it is Loading Loading @@ -6246,6 +6289,7 @@ public class Intent implements Parcelable, Cloneable { * @see #FLAG_ACTIVITY_FORWARD_RESULT * @see #FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY * @see #FLAG_ACTIVITY_MULTIPLE_TASK * @see #FLAG_ACTIVITY_NEW_DOCUMENT * @see #FLAG_ACTIVITY_NEW_TASK * @see #FLAG_ACTIVITY_NO_ANIMATION * @see #FLAG_ACTIVITY_NO_HISTORY Loading Loading @@ -7342,4 +7386,9 @@ public class Intent implements Parcelable, Cloneable { String htmlText = htmlTexts != null ? htmlTexts.get(which) : null; return new ClipData.Item(text, htmlText, null, uri); } /** @hide */ public boolean isDocument() { return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT; } } services/core/java/com/android/server/am/ActivityManagerService.java +26 −11 Original line number Diff line number Diff line Loading @@ -3319,11 +3319,27 @@ public final class ActivityManagerService extends ActivityManagerNative return; } // Remove any existing entries that are the same kind of task. final Intent intent = task.intent; final boolean document = intent != null && intent.isDocument(); for (int i=0; i<N; i++) { TaskRecord tr = mRecentTasks.get(i); if (task.userId == tr.userId && ((task.affinity != null && task.affinity.equals(tr.affinity)) || (task.intent != null && task.intent.filterEquals(tr.intent)))) { if (task != tr) { if (task.userId != tr.userId) { continue; } final Intent trIntent = tr.intent; if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && (intent == null || !intent.filterEquals(trIntent))) { continue; } if (document || trIntent != null && trIntent.isDocument()) { // Document tasks do not match other tasks. continue; } } // Either task and tr are the same or, their affinities match or their intents match // and neither of them is a document. tr.disposeThumbnail(); mRecentTasks.remove(i); i--; Loading @@ -3334,7 +3350,6 @@ public final class ActivityManagerService extends ActivityManagerNative task = tr; } } } if (N >= MAX_RECENT_TASKS) { mRecentTasks.remove(N-1).disposeThumbnail(); } Loading services/core/java/com/android/server/am/ActivityStack.java +28 −16 Original line number Diff line number Diff line Loading @@ -492,6 +492,9 @@ final class ActivityStack { cls = new ComponentName(info.packageName, info.targetActivity); } final int userId = UserHandle.getUserId(info.applicationInfo.uid); boolean isDocument = intent != null & intent.isDocument(); // If documentData is non-null then it must match the existing task data. Uri documentData = isDocument ? intent.getData() : null; if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + target + " in " + this); for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { Loading @@ -508,23 +511,39 @@ final class ActivityStack { continue; } final Intent taskIntent = task.intent; final Intent affinityIntent = task.affinityIntent; final boolean taskIsDocument; final Uri taskDocumentData; if (taskIntent != null && taskIntent.isDocument()) { taskIsDocument = true; taskDocumentData = taskIntent.getData(); } else if (affinityIntent != null && affinityIntent.isDocument()) { taskIsDocument = true; taskDocumentData = affinityIntent.getData(); } else { taskIsDocument = false; taskDocumentData = null; } if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() + taskIntent.getComponent().flattenToShortString() + "/aff=" + r.task.affinity + " to new cls=" + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity); if (task.affinity != null) { if (task.affinity.equals(info.taskAffinity)) { if (!isDocument && !taskIsDocument && task.affinity != null) { if (task.affinity.equals(target.taskAffinity)) { if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!"); return r; } } else if (task.intent != null && task.intent.getComponent().equals(cls)) { } else if (taskIntent != null && taskIntent.getComponent().equals(cls) && Objects.equals(documentData, taskDocumentData)) { if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!"); //dump(); if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: " + r.intent); return r; } else if (task.affinityIntent != null && task.affinityIntent.getComponent().equals(cls)) { } else if (affinityIntent != null && affinityIntent.getComponent().equals(cls) && Objects.equals(documentData, taskDocumentData)) { if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!"); //dump(); if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: " Loading Loading @@ -2006,14 +2025,7 @@ final class ActivityStack { + " out to new task " + target.task); } if (clearWhenTaskReset) { // This is the start of a new sub-task. if (target.thumbHolder == null) { target.thumbHolder = new ThumbnailHolder(); } } else { target.thumbHolder = newThumbHolder; } final int targetTaskId = targetTask.taskId; mWindowManager.setAppGroupId(target.appToken, targetTaskId); Loading services/core/java/com/android/server/am/ActivityStackSupervisor.java +13 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.am; import static android.Manifest.permission.START_ANY_ACTIVITY; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; import static android.content.pm.PackageManager.PERMISSION_GRANTED; Loading Loading @@ -1443,6 +1444,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } } 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. Loading @@ -1451,6 +1453,11 @@ 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 Loading Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6849,6 +6849,7 @@ package android.content { 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_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
core/java/android/content/Intent.java +52 −3 Original line number Diff line number Diff line Loading @@ -3457,7 +3457,16 @@ public class Intent implements Parcelable, Cloneable { */ public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000; /** * <strong>Do not use this flag unless you are implementing your own * This flag is used to create a new task and launch an activity into it. * This flag is always paired with either {@link #FLAG_ACTIVITY_NEW_DOCUMENT} * or {@link #FLAG_ACTIVITY_NEW_TASK}. In both cases these flags alone would * search through existing tasks for ones matching this Intent. Only if no such * task is found would a new task be created. When paired with * FLAG_ACTIVITY_MULTIPLE_TASK both of these behaviors are modified to skip * the search for a matching task and unconditionally start a new task. * * <strong>When used with {@link #FLAG_ACTIVITY_NEW_TASK} do not use this * flag unless you are implementing your own * top-level application launcher.</strong> Used in conjunction with * {@link #FLAG_ACTIVITY_NEW_TASK} to disable the * behavior of bringing an existing task to the foreground. When set, Loading @@ -3469,12 +3478,18 @@ public class Intent implements Parcelable, Cloneable { * you should not use this flag unless you provide some way for a user to * return back to the tasks you have launched.</strong> * * <p>This flag is ignored if * {@link #FLAG_ACTIVITY_NEW_TASK} is not set. * See {@link #FLAG_ACTIVITY_NEW_DOCUMENT} for details of this flag's use for * creating new document tasks. * * <p>This flag is ignored if one of {@link #FLAG_ACTIVITY_NEW_TASK} or * {@link #FLAG_ACTIVITY_NEW_TASK} is not also set. * * <p>See * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back * Stack</a> for more information about tasks. * * @see #FLAG_ACTIVITY_NEW_DOCUMENT * @see #FLAG_ACTIVITY_NEW_TASK */ public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000; /** Loading Loading @@ -3580,6 +3595,34 @@ public class Intent implements Parcelable, Cloneable { * to mail. */ public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000; /** * This flag is used to break out "documents" into separate tasks that can * be reached via the Recents mechanism. Such a document is any kind of * item for which an application may want to maintain multiple simultaneous * instances. Examples might be text files, web pages, spreadsheets, or * emails. Each such document will be in a separate task in the Recents list. * * <p>When set, the activity specified by this Intent will launch into a * separate task rooted at that activity. The activity launched must be * defined with {@link android.R.attr#launchMode} "standard" or "singleTop". * * <p>If FLAG_ACTIVITY_NEW_DOCUMENT is used without * {@link #FLAG_ACTIVITY_MULTIPLE_TASK} then the activity manager will * search for an existing task with a matching target activity and Intent * data URI and relaunch that task, first finishing all activities down to * the root activity and then calling the root activity's * {@link android.app.Activity#onNewIntent(Intent)} method. If no existing * task's root activity matches the Intent's data URI then a new task will * be launched with the target activity as root. * * <p>When paired with {@link #FLAG_ACTIVITY_MULTIPLE_TASK} this will * always create a new task. Thus the same document may be made to appear * more than one time in Recents. * * @see #FLAG_ACTIVITY_MULTIPLE_TASK */ public static final int FLAG_ACTIVITY_NEW_DOCUMENT = FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | FLAG_ACTIVITY_NEW_TASK; /** * If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaveHint} * callback from occurring on the current frontmost activity before it is Loading Loading @@ -6246,6 +6289,7 @@ public class Intent implements Parcelable, Cloneable { * @see #FLAG_ACTIVITY_FORWARD_RESULT * @see #FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY * @see #FLAG_ACTIVITY_MULTIPLE_TASK * @see #FLAG_ACTIVITY_NEW_DOCUMENT * @see #FLAG_ACTIVITY_NEW_TASK * @see #FLAG_ACTIVITY_NO_ANIMATION * @see #FLAG_ACTIVITY_NO_HISTORY Loading Loading @@ -7342,4 +7386,9 @@ public class Intent implements Parcelable, Cloneable { String htmlText = htmlTexts != null ? htmlTexts.get(which) : null; return new ClipData.Item(text, htmlText, null, uri); } /** @hide */ public boolean isDocument() { return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT; } }
services/core/java/com/android/server/am/ActivityManagerService.java +26 −11 Original line number Diff line number Diff line Loading @@ -3319,11 +3319,27 @@ public final class ActivityManagerService extends ActivityManagerNative return; } // Remove any existing entries that are the same kind of task. final Intent intent = task.intent; final boolean document = intent != null && intent.isDocument(); for (int i=0; i<N; i++) { TaskRecord tr = mRecentTasks.get(i); if (task.userId == tr.userId && ((task.affinity != null && task.affinity.equals(tr.affinity)) || (task.intent != null && task.intent.filterEquals(tr.intent)))) { if (task != tr) { if (task.userId != tr.userId) { continue; } final Intent trIntent = tr.intent; if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && (intent == null || !intent.filterEquals(trIntent))) { continue; } if (document || trIntent != null && trIntent.isDocument()) { // Document tasks do not match other tasks. continue; } } // Either task and tr are the same or, their affinities match or their intents match // and neither of them is a document. tr.disposeThumbnail(); mRecentTasks.remove(i); i--; Loading @@ -3334,7 +3350,6 @@ public final class ActivityManagerService extends ActivityManagerNative task = tr; } } } if (N >= MAX_RECENT_TASKS) { mRecentTasks.remove(N-1).disposeThumbnail(); } Loading
services/core/java/com/android/server/am/ActivityStack.java +28 −16 Original line number Diff line number Diff line Loading @@ -492,6 +492,9 @@ final class ActivityStack { cls = new ComponentName(info.packageName, info.targetActivity); } final int userId = UserHandle.getUserId(info.applicationInfo.uid); boolean isDocument = intent != null & intent.isDocument(); // If documentData is non-null then it must match the existing task data. Uri documentData = isDocument ? intent.getData() : null; if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + target + " in " + this); for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { Loading @@ -508,23 +511,39 @@ final class ActivityStack { continue; } final Intent taskIntent = task.intent; final Intent affinityIntent = task.affinityIntent; final boolean taskIsDocument; final Uri taskDocumentData; if (taskIntent != null && taskIntent.isDocument()) { taskIsDocument = true; taskDocumentData = taskIntent.getData(); } else if (affinityIntent != null && affinityIntent.isDocument()) { taskIsDocument = true; taskDocumentData = affinityIntent.getData(); } else { taskIsDocument = false; taskDocumentData = null; } if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() + taskIntent.getComponent().flattenToShortString() + "/aff=" + r.task.affinity + " to new cls=" + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity); if (task.affinity != null) { if (task.affinity.equals(info.taskAffinity)) { if (!isDocument && !taskIsDocument && task.affinity != null) { if (task.affinity.equals(target.taskAffinity)) { if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!"); return r; } } else if (task.intent != null && task.intent.getComponent().equals(cls)) { } else if (taskIntent != null && taskIntent.getComponent().equals(cls) && Objects.equals(documentData, taskDocumentData)) { if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!"); //dump(); if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: " + r.intent); return r; } else if (task.affinityIntent != null && task.affinityIntent.getComponent().equals(cls)) { } else if (affinityIntent != null && affinityIntent.getComponent().equals(cls) && Objects.equals(documentData, taskDocumentData)) { if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!"); //dump(); if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: " Loading Loading @@ -2006,14 +2025,7 @@ final class ActivityStack { + " out to new task " + target.task); } if (clearWhenTaskReset) { // This is the start of a new sub-task. if (target.thumbHolder == null) { target.thumbHolder = new ThumbnailHolder(); } } else { target.thumbHolder = newThumbHolder; } final int targetTaskId = targetTask.taskId; mWindowManager.setAppGroupId(target.appToken, targetTaskId); Loading
services/core/java/com/android/server/am/ActivityStackSupervisor.java +13 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.am; import static android.Manifest.permission.START_ANY_ACTIVITY; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; import static android.content.pm.PackageManager.PERMISSION_GRANTED; Loading Loading @@ -1443,6 +1444,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } } 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. Loading @@ -1451,6 +1453,11 @@ 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 Loading