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