1dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell/*
2dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Copyright (C) 2012 The Android Open Source Project
3dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
4dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * you may not use this file except in compliance with the License.
6dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * You may obtain a copy of the License at
7dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
8dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
10dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Unless required by applicable law or agreed to in writing, software
11dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * See the License for the specific language governing permissions and
14dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * limitations under the License.
15dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell */
16dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
17dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellpackage android.app;
18dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
19d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbyeimport android.annotation.NonNull;
20dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.ComponentName;
21dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.Context;
22dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.Intent;
23dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.pm.ActivityInfo;
24dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.pm.PackageManager;
25dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.pm.PackageManager.NameNotFoundException;
26f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powellimport android.os.Bundle;
27ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasaniimport android.os.UserHandle;
28dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.util.Log;
29dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
30dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport java.util.ArrayList;
31dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
32dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell/**
33dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Utility class for constructing synthetic back stacks for cross-task navigation
34dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * on Android 3.0 and newer.
35dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
36dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for
37dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * app navigation using the back key changed. The back key's behavior is local
38dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * to the current task and does not capture navigation across different tasks.
39dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Navigating across tasks and easily reaching the previous task is accomplished
40dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * through the "recents" UI, accessible through the software-provided Recents key
41dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * on the navigation or system bar. On devices with the older hardware button configuration
42dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * the recents UI can be accessed with a long press on the Home key.</p>
43dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
44dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <p>When crossing from one task stack to another post-Android 3.0,
45dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * the application should synthesize a back stack/history for the new task so that
46dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * the user may navigate out of the new task and back to the Launcher by repeated
47dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * presses of the back key. Back key presses should not navigate across task stacks.</p>
48dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
49dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <p>TaskStackBuilder provides a way to obey the correct conventions
50dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * around cross-task navigation.</p>
51dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
52dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <div class="special reference">
53dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <h3>About Navigation</h3>
54dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * For more detailed information about tasks, the back stack, and navigation design guidelines,
55dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * please read
56dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
57dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * from the developer guide and <a href="{@docRoot}design/patterns/navigation.html">Navigation</a>
58dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * from the design guide.
59dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * </div>
60dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell */
61f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powellpublic class TaskStackBuilder {
62dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    private static final String TAG = "TaskStackBuilder";
63dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
64dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    private final ArrayList<Intent> mIntents = new ArrayList<Intent>();
65dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    private final Context mSourceContext;
66dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
67dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    private TaskStackBuilder(Context a) {
68dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        mSourceContext = a;
69dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
70dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
71dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
72dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Return a new TaskStackBuilder for launching a fresh task stack consisting
73dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * of a series of activities.
74dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
75dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param context The context that will launch the new task stack or generate a PendingIntent
76dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return A new TaskStackBuilder
77dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
78f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public static TaskStackBuilder create(Context context) {
79dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return new TaskStackBuilder(context);
80dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
81dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
82dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
83dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Add a new Intent to the task stack. The most recently added Intent will invoke
84dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * the Activity at the top of the final task stack.
85dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
86dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param nextIntent Intent for the next Activity in the synthesized task stack
87dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return This TaskStackBuilder for method chaining
88dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
89dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    public TaskStackBuilder addNextIntent(Intent nextIntent) {
90dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        mIntents.add(nextIntent);
91dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return this;
92dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
93dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
94dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
95f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Add a new Intent with the resolved chain of parents for the target activity to
96f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * the task stack.
97f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
98f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * <p>This is equivalent to calling {@link #addParentStack(ComponentName) addParentStack}
99f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * with the resolved ComponentName of nextIntent (if it can be resolved), followed by
100f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * {@link #addNextIntent(Intent) addNextIntent} with nextIntent.</p>
101f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
102f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @param nextIntent Intent for the topmost Activity in the synthesized task stack.
103f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *                   Its chain of parents as specified in the manifest will be added.
104f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @return This TaskStackBuilder for method chaining.
105f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     */
106f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public TaskStackBuilder addNextIntentWithParentStack(Intent nextIntent) {
107f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        ComponentName target = nextIntent.getComponent();
108f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        if (target == null) {
109f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell            target = nextIntent.resolveActivity(mSourceContext.getPackageManager());
110f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        }
111f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        if (target != null) {
112f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell            addParentStack(target);
113f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        }
114f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        addNextIntent(nextIntent);
115f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        return this;
116f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    }
117f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell
118f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    /**
119dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Add the activity parent chain as specified by the
1203c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * {@link Activity#getParentActivityIntent() getParentActivityIntent()} method of the activity
1213c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * specified and the {@link android.R.attr#parentActivityName parentActivityName} attributes
1223c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * of each successive activity (or activity-alias) element in the application's manifest
1233c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * to the task stack builder.
124dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
125dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param sourceActivity All parents of this activity will be added
126dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return This TaskStackBuilder for method chaining
127dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
128dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    public TaskStackBuilder addParentStack(Activity sourceActivity) {
1295a4010c054a4449156df885ad0f46f8db3263d87Adam Powell        final Intent parent = sourceActivity.getParentActivityIntent();
1305a4010c054a4449156df885ad0f46f8db3263d87Adam Powell        if (parent != null) {
1315a4010c054a4449156df885ad0f46f8db3263d87Adam Powell            // We have the actual parent intent, build the rest from static metadata
1325a4010c054a4449156df885ad0f46f8db3263d87Adam Powell            // then add the direct parent intent to the end.
1339ceac5a02f08bc350d6047660ed75019313f4703Adam Powell            ComponentName target = parent.getComponent();
1349ceac5a02f08bc350d6047660ed75019313f4703Adam Powell            if (target == null) {
1359ceac5a02f08bc350d6047660ed75019313f4703Adam Powell                target = parent.resolveActivity(mSourceContext.getPackageManager());
1369ceac5a02f08bc350d6047660ed75019313f4703Adam Powell            }
1379ceac5a02f08bc350d6047660ed75019313f4703Adam Powell            addParentStack(target);
1385a4010c054a4449156df885ad0f46f8db3263d87Adam Powell            addNextIntent(parent);
139dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        }
140dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return this;
141dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
142dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
143dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
144dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Add the activity parent chain as specified by the
145dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
146dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * (or activity-alias) element in the application's manifest to the task stack builder.
147dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
148dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param sourceActivityClass All parents of this activity will be added
149dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return This TaskStackBuilder for method chaining
150dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
151dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    public TaskStackBuilder addParentStack(Class<?> sourceActivityClass) {
1525a4010c054a4449156df885ad0f46f8db3263d87Adam Powell        return addParentStack(new ComponentName(mSourceContext, sourceActivityClass));
153dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
154dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
155dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
1563c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * Add the activity parent chain as specified by the
1573c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
1583c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * (or activity-alias) element in the application's manifest to the task stack builder.
1593c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     *
1603c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * @param sourceActivityName Must specify an Activity component. All parents of
1613c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     *                           this activity will be added
1623c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * @return This TaskStackBuilder for method chaining
1633c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     */
1643c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell    public TaskStackBuilder addParentStack(ComponentName sourceActivityName) {
1653c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        final int insertAt = mIntents.size();
1663c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        PackageManager pm = mSourceContext.getPackageManager();
1673c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        try {
1683c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            ActivityInfo info = pm.getActivityInfo(sourceActivityName, 0);
1693c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            String parentActivity = info.parentActivityName;
1705c43ec9328ba98fa88acc452b140f2d682a3042cAdam Powell            while (parentActivity != null) {
1716b6c90523ed8779aa962ff4f5ef8c368a96269e2Adam Powell                final ComponentName target = new ComponentName(info.packageName, parentActivity);
1725a4010c054a4449156df885ad0f46f8db3263d87Adam Powell                info = pm.getActivityInfo(target, 0);
1733c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell                parentActivity = info.parentActivityName;
1745a4010c054a4449156df885ad0f46f8db3263d87Adam Powell                final Intent parent = parentActivity == null && insertAt == 0
1755a4010c054a4449156df885ad0f46f8db3263d87Adam Powell                        ? Intent.makeMainActivity(target)
1765a4010c054a4449156df885ad0f46f8db3263d87Adam Powell                        : new Intent().setComponent(target);
1775a4010c054a4449156df885ad0f46f8db3263d87Adam Powell                mIntents.add(insertAt, parent);
1783c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            }
1793c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        } catch (NameNotFoundException e) {
1803c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
1813c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            throw new IllegalArgumentException(e);
1823c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        }
1833c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        return this;
1843c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell    }
1853c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell
1863c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell    /**
187dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return the number of intents added so far.
188dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
189dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    public int getIntentCount() {
190dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return mIntents.size();
191dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
192dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
193dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
194f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Return the intent at the specified index for modification.
195dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Useful if you need to modify the flags or extras of an intent that was previously added,
196dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * for example with {@link #addParentStack(Activity)}.
197dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
198dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param index Index from 0-getIntentCount()
199dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return the intent at position index
200dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
201f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public Intent editIntentAt(int index) {
202dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return mIntents.get(index);
203dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
204dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
205f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    /**
206f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Start the task stack constructed by this builder.
207f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     */
208f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public void startActivities() {
209f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        startActivities(null);
210dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
211dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
212dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
213dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Start the task stack constructed by this builder.
214ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani     * @hide
215dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
216ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani    public void startActivities(Bundle options, UserHandle userHandle) {
217dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        if (mIntents.isEmpty()) {
218dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            throw new IllegalStateException(
219dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                    "No intents added to TaskStackBuilder; cannot startActivities");
220dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        }
221dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
222ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani        mSourceContext.startActivitiesAsUser(getIntents(), options, userHandle);
223ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani    }
224ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani
225ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani    /**
226ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani     * Start the task stack constructed by this builder.
227ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani     *
228ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani     * @param options Additional options for how the Activity should be started.
229ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani     * See {@link android.content.Context#startActivity(Intent, Bundle)
230ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani     * Context.startActivity(Intent, Bundle)} for more details.
231ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani     */
232ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani    public void startActivities(Bundle options) {
233ea7e91514ee1968d15713e82a5cca745e2c46a05Amith Yamasani        startActivities(options, new UserHandle(UserHandle.myUserId()));
234dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
235dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
236dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
237dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Obtain a {@link PendingIntent} for launching the task constructed by this builder so far.
238dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
239dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param requestCode Private request code for the sender
240dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT},
241dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *              {@link PendingIntent#FLAG_NO_CREATE}, {@link PendingIntent#FLAG_CANCEL_CURRENT},
242dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *              {@link PendingIntent#FLAG_UPDATE_CURRENT}, or any of the flags supported by
243dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *              {@link Intent#fillIn(Intent, int)} to control which unspecified parts of the
244dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *              intent that can be supplied when the actual send happens.
245f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
246dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return The obtained PendingIntent
247dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
248d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    public PendingIntent getPendingIntent(int requestCode, @PendingIntent.Flags int flags) {
249f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        return getPendingIntent(requestCode, flags, null);
250f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    }
251f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell
252f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    /**
253f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Obtain a {@link PendingIntent} for launching the task constructed by this builder so far.
254f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
255f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @param requestCode Private request code for the sender
256f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT},
257f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *              {@link PendingIntent#FLAG_NO_CREATE}, {@link PendingIntent#FLAG_CANCEL_CURRENT},
258f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *              {@link PendingIntent#FLAG_UPDATE_CURRENT}, or any of the flags supported by
259f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *              {@link Intent#fillIn(Intent, int)} to control which unspecified parts of the
260f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *              intent that can be supplied when the actual send happens.
261f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @param options Additional options for how the Activity should be started.
262f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * See {@link android.content.Context#startActivity(Intent, Bundle)
263f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Context.startActivity(Intent, Bundle)} for more details.
264f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
265f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @return The obtained PendingIntent
266f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     */
267d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    public PendingIntent getPendingIntent(int requestCode, @PendingIntent.Flags int flags,
268d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye            Bundle options) {
2698ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell        if (mIntents.isEmpty()) {
2708ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell            throw new IllegalStateException(
2718ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell                    "No intents added to TaskStackBuilder; cannot getPendingIntent");
2728ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell        }
2738ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell
27475e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell        return PendingIntent.getActivities(mSourceContext, requestCode, getIntents(),
27575e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell                flags, options);
276f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    }
277f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell
278f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    /**
279d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell     * @hide
280d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell     */
281d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell    public PendingIntent getPendingIntent(int requestCode, int flags, Bundle options,
282d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell            UserHandle user) {
283d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell        if (mIntents.isEmpty()) {
284d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell            throw new IllegalStateException(
285d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell                    "No intents added to TaskStackBuilder; cannot getPendingIntent");
286d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell        }
287d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell
288d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell        return PendingIntent.getActivitiesAsUser(mSourceContext, requestCode, getIntents(), flags,
289d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell                options, user);
290d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell    }
291d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell
292d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell    /**
293f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Return an array containing the intents added to this builder. The intent at the
294f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * root of the task stack will appear as the first item in the array and the
295f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * intent at the top of the stack will appear as the last item.
296f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
297f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @return An array containing the intents added to this builder.
298f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     */
299d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    @NonNull
300f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public Intent[] getIntents() {
30175e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell        Intent[] intents = new Intent[mIntents.size()];
30275e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell        if (intents.length == 0) return intents;
30375e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell
30475e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell        intents[0] = new Intent(mIntents.get(0)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
30575e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell                Intent.FLAG_ACTIVITY_CLEAR_TASK |
30675e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell                Intent.FLAG_ACTIVITY_TASK_ON_HOME);
30775e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell        for (int i = 1; i < intents.length; i++) {
30875e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell            intents[i] = new Intent(mIntents.get(i));
30975e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell        }
31075e0af8982cd29cfe8a01c18d1e82d7abcfd1711Adam Powell        return intents;
311dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
312dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell}
313