Activity.java revision 39791594560b2326625b663ed6796882900c220f
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import android.graphics.Rect;
20import android.view.ViewRootImpl.ActivityConfigCallback;
21import android.view.autofill.AutofillManager;
22import android.view.autofill.AutofillPopupWindow;
23import android.view.autofill.IAutofillWindowPresenter;
24import com.android.internal.annotations.GuardedBy;
25import com.android.internal.app.IVoiceInteractor;
26import com.android.internal.app.ToolbarActionBar;
27import com.android.internal.app.WindowDecorActionBar;
28import com.android.internal.policy.DecorView;
29import com.android.internal.policy.PhoneWindow;
30
31import android.annotation.CallSuper;
32import android.annotation.DrawableRes;
33import android.annotation.IdRes;
34import android.annotation.IntDef;
35import android.annotation.LayoutRes;
36import android.annotation.MainThread;
37import android.annotation.NonNull;
38import android.annotation.Nullable;
39import android.annotation.RequiresPermission;
40import android.annotation.StyleRes;
41import android.annotation.SystemApi;
42import android.app.VoiceInteractor.Request;
43import android.app.admin.DevicePolicyManager;
44import android.app.assist.AssistContent;
45import android.content.ComponentCallbacks2;
46import android.content.ComponentName;
47import android.content.ContentResolver;
48import android.content.Context;
49import android.content.CursorLoader;
50import android.content.IIntentSender;
51import android.content.Intent;
52import android.content.IntentSender;
53import android.content.SharedPreferences;
54import android.content.pm.ActivityInfo;
55import android.content.pm.ApplicationInfo;
56import android.content.pm.PackageManager;
57import android.content.pm.PackageManager.NameNotFoundException;
58import android.content.res.Configuration;
59import android.content.res.Resources;
60import android.content.res.TypedArray;
61import android.database.Cursor;
62import android.graphics.Bitmap;
63import android.graphics.Canvas;
64import android.graphics.Color;
65import android.graphics.drawable.Drawable;
66import android.media.AudioManager;
67import android.media.session.MediaController;
68import android.net.Uri;
69import android.os.BadParcelableException;
70import android.os.Build;
71import android.os.Bundle;
72import android.os.Handler;
73import android.os.IBinder;
74import android.os.Looper;
75import android.os.Parcelable;
76import android.os.PersistableBundle;
77import android.os.RemoteException;
78import android.os.ServiceManager.ServiceNotFoundException;
79import android.os.StrictMode;
80import android.os.SystemProperties;
81import android.os.UserHandle;
82import android.text.Selection;
83import android.text.SpannableStringBuilder;
84import android.text.TextUtils;
85import android.text.method.TextKeyListener;
86import android.transition.Scene;
87import android.transition.TransitionManager;
88import android.util.ArrayMap;
89import android.util.AttributeSet;
90import android.util.EventLog;
91import android.util.Log;
92import android.util.PrintWriterPrinter;
93import android.util.Slog;
94import android.util.SparseArray;
95import android.util.SuperNotCalledException;
96import android.view.ActionMode;
97import android.view.ContextMenu;
98import android.view.ContextMenu.ContextMenuInfo;
99import android.view.ContextThemeWrapper;
100import android.view.DragAndDropPermissions;
101import android.view.DragEvent;
102import android.view.KeyEvent;
103import android.view.KeyboardShortcutGroup;
104import android.view.KeyboardShortcutInfo;
105import android.view.LayoutInflater;
106import android.view.Menu;
107import android.view.MenuInflater;
108import android.view.MenuItem;
109import android.view.MotionEvent;
110import android.view.SearchEvent;
111import android.view.View;
112import android.view.View.OnCreateContextMenuListener;
113import android.view.ViewGroup;
114import android.view.ViewGroup.LayoutParams;
115import android.view.ViewManager;
116import android.view.ViewRootImpl;
117import android.view.Window;
118import android.view.Window.WindowControllerCallback;
119import android.view.WindowManager;
120import android.view.WindowManagerGlobal;
121import android.view.accessibility.AccessibilityEvent;
122import android.widget.AdapterView;
123import android.widget.Toast;
124import android.widget.Toolbar;
125
126import java.io.FileDescriptor;
127import java.io.PrintWriter;
128import java.lang.annotation.Retention;
129import java.lang.annotation.RetentionPolicy;
130import java.util.ArrayList;
131import java.util.HashMap;
132import java.util.List;
133
134import static android.os.Build.VERSION_CODES.O;
135import static java.lang.Character.MIN_VALUE;
136
137/**
138 * An activity is a single, focused thing that the user can do.  Almost all
139 * activities interact with the user, so the Activity class takes care of
140 * creating a window for you in which you can place your UI with
141 * {@link #setContentView}.  While activities are often presented to the user
142 * as full-screen windows, they can also be used in other ways: as floating
143 * windows (via a theme with {@link android.R.attr#windowIsFloating} set)
144 * or embedded inside of another activity (using {@link ActivityGroup}).
145 *
146 * There are two methods almost all subclasses of Activity will implement:
147 *
148 * <ul>
149 *     <li> {@link #onCreate} is where you initialize your activity.  Most
150 *     importantly, here you will usually call {@link #setContentView(int)}
151 *     with a layout resource defining your UI, and using {@link #findViewById}
152 *     to retrieve the widgets in that UI that you need to interact with
153 *     programmatically.
154 *
155 *     <li> {@link #onPause} is where you deal with the user leaving your
156 *     activity.  Most importantly, any changes made by the user should at this
157 *     point be committed (usually to the
158 *     {@link android.content.ContentProvider} holding the data).
159 * </ul>
160 *
161 * <p>To be of use with {@link android.content.Context#startActivity Context.startActivity()}, all
162 * activity classes must have a corresponding
163 * {@link android.R.styleable#AndroidManifestActivity &lt;activity&gt;}
164 * declaration in their package's <code>AndroidManifest.xml</code>.</p>
165 *
166 * <p>Topics covered here:
167 * <ol>
168 * <li><a href="#Fragments">Fragments</a>
169 * <li><a href="#ActivityLifecycle">Activity Lifecycle</a>
170 * <li><a href="#ConfigurationChanges">Configuration Changes</a>
171 * <li><a href="#StartingActivities">Starting Activities and Getting Results</a>
172 * <li><a href="#SavingPersistentState">Saving Persistent State</a>
173 * <li><a href="#Permissions">Permissions</a>
174 * <li><a href="#ProcessLifecycle">Process Lifecycle</a>
175 * </ol>
176 *
177 * <div class="special reference">
178 * <h3>Developer Guides</h3>
179 * <p>The Activity class is an important part of an application's overall lifecycle,
180 * and the way activities are launched and put together is a fundamental
181 * part of the platform's application model. For a detailed perspective on the structure of an
182 * Android application and how activities behave, please read the
183 * <a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> and
184 * <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a>
185 * developer guides.</p>
186 *
187 * <p>You can also find a detailed discussion about how to create activities in the
188 * <a href="{@docRoot}guide/components/activities.html">Activities</a>
189 * developer guide.</p>
190 * </div>
191 *
192 * <a name="Fragments"></a>
193 * <h3>Fragments</h3>
194 *
195 * <p>Starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB}, Activity
196 * implementations can make use of the {@link Fragment} class to better
197 * modularize their code, build more sophisticated user interfaces for larger
198 * screens, and help scale their application between small and large screens.
199 *
200 * <a name="ActivityLifecycle"></a>
201 * <h3>Activity Lifecycle</h3>
202 *
203 * <p>Activities in the system are managed as an <em>activity stack</em>.
204 * When a new activity is started, it is placed on the top of the stack
205 * and becomes the running activity -- the previous activity always remains
206 * below it in the stack, and will not come to the foreground again until
207 * the new activity exits.</p>
208 *
209 * <p>An activity has essentially four states:</p>
210 * <ul>
211 *     <li> If an activity is in the foreground of the screen (at the top of
212 *         the stack),
213 *         it is <em>active</em> or  <em>running</em>. </li>
214 *     <li>If an activity has lost focus but is still visible (that is, a new non-full-sized
215 *         or transparent activity has focus on top of your activity), it
216 *         is <em>paused</em>. A paused activity is completely alive (it
217 *         maintains all state and member information and remains attached to
218 *         the window manager), but can be killed by the system in extreme
219 *         low memory situations.
220 *     <li>If an activity is completely obscured by another activity,
221 *         it is <em>stopped</em>. It still retains all state and member information,
222 *         however, it is no longer visible to the user so its window is hidden
223 *         and it will often be killed by the system when memory is needed
224 *         elsewhere.</li>
225 *     <li>If an activity is paused or stopped, the system can drop the activity
226 *         from memory by either asking it to finish, or simply killing its
227 *         process.  When it is displayed again to the user, it must be
228 *         completely restarted and restored to its previous state.</li>
229 * </ul>
230 *
231 * <p>The following diagram shows the important state paths of an Activity.
232 * The square rectangles represent callback methods you can implement to
233 * perform operations when the Activity moves between states.  The colored
234 * ovals are major states the Activity can be in.</p>
235 *
236 * <p><img src="../../../images/activity_lifecycle.png"
237 *      alt="State diagram for an Android Activity Lifecycle." border="0" /></p>
238 *
239 * <p>There are three key loops you may be interested in monitoring within your
240 * activity:
241 *
242 * <ul>
243 * <li>The <b>entire lifetime</b> of an activity happens between the first call
244 * to {@link android.app.Activity#onCreate} through to a single final call
245 * to {@link android.app.Activity#onDestroy}.  An activity will do all setup
246 * of "global" state in onCreate(), and release all remaining resources in
247 * onDestroy().  For example, if it has a thread running in the background
248 * to download data from the network, it may create that thread in onCreate()
249 * and then stop the thread in onDestroy().
250 *
251 * <li>The <b>visible lifetime</b> of an activity happens between a call to
252 * {@link android.app.Activity#onStart} until a corresponding call to
253 * {@link android.app.Activity#onStop}.  During this time the user can see the
254 * activity on-screen, though it may not be in the foreground and interacting
255 * with the user.  Between these two methods you can maintain resources that
256 * are needed to show the activity to the user.  For example, you can register
257 * a {@link android.content.BroadcastReceiver} in onStart() to monitor for changes
258 * that impact your UI, and unregister it in onStop() when the user no
259 * longer sees what you are displaying.  The onStart() and onStop() methods
260 * can be called multiple times, as the activity becomes visible and hidden
261 * to the user.
262 *
263 * <li>The <b>foreground lifetime</b> of an activity happens between a call to
264 * {@link android.app.Activity#onResume} until a corresponding call to
265 * {@link android.app.Activity#onPause}.  During this time the activity is
266 * in front of all other activities and interacting with the user.  An activity
267 * can frequently go between the resumed and paused states -- for example when
268 * the device goes to sleep, when an activity result is delivered, when a new
269 * intent is delivered -- so the code in these methods should be fairly
270 * lightweight.
271 * </ul>
272 *
273 * <p>The entire lifecycle of an activity is defined by the following
274 * Activity methods.  All of these are hooks that you can override
275 * to do appropriate work when the activity changes state.  All
276 * activities will implement {@link android.app.Activity#onCreate}
277 * to do their initial setup; many will also implement
278 * {@link android.app.Activity#onPause} to commit changes to data and
279 * otherwise prepare to stop interacting with the user.  You should always
280 * call up to your superclass when implementing these methods.</p>
281 *
282 * </p>
283 * <pre class="prettyprint">
284 * public class Activity extends ApplicationContext {
285 *     protected void onCreate(Bundle savedInstanceState);
286 *
287 *     protected void onStart();
288 *
289 *     protected void onRestart();
290 *
291 *     protected void onResume();
292 *
293 *     protected void onPause();
294 *
295 *     protected void onStop();
296 *
297 *     protected void onDestroy();
298 * }
299 * </pre>
300 *
301 * <p>In general the movement through an activity's lifecycle looks like
302 * this:</p>
303 *
304 * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
305 *     <colgroup align="left" span="3" />
306 *     <colgroup align="left" />
307 *     <colgroup align="center" />
308 *     <colgroup align="center" />
309 *
310 *     <thead>
311 *     <tr><th colspan="3">Method</th> <th>Description</th> <th>Killable?</th> <th>Next</th></tr>
312 *     </thead>
313 *
314 *     <tbody>
315 *     <tr><td colspan="3" align="left" border="0">{@link android.app.Activity#onCreate onCreate()}</td>
316 *         <td>Called when the activity is first created.
317 *             This is where you should do all of your normal static set up:
318 *             create views, bind data to lists, etc.  This method also
319 *             provides you with a Bundle containing the activity's previously
320 *             frozen state, if there was one.
321 *             <p>Always followed by <code>onStart()</code>.</td>
322 *         <td align="center">No</td>
323 *         <td align="center"><code>onStart()</code></td>
324 *     </tr>
325 *
326 *     <tr><td rowspan="5" style="border-left: none; border-right: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
327 *         <td colspan="2" align="left" border="0">{@link android.app.Activity#onRestart onRestart()}</td>
328 *         <td>Called after your activity has been stopped, prior to it being
329 *             started again.
330 *             <p>Always followed by <code>onStart()</code></td>
331 *         <td align="center">No</td>
332 *         <td align="center"><code>onStart()</code></td>
333 *     </tr>
334 *
335 *     <tr><td colspan="2" align="left" border="0">{@link android.app.Activity#onStart onStart()}</td>
336 *         <td>Called when the activity is becoming visible to the user.
337 *             <p>Followed by <code>onResume()</code> if the activity comes
338 *             to the foreground, or <code>onStop()</code> if it becomes hidden.</td>
339 *         <td align="center">No</td>
340 *         <td align="center"><code>onResume()</code> or <code>onStop()</code></td>
341 *     </tr>
342 *
343 *     <tr><td rowspan="2" style="border-left: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
344 *         <td align="left" border="0">{@link android.app.Activity#onResume onResume()}</td>
345 *         <td>Called when the activity will start
346 *             interacting with the user.  At this point your activity is at
347 *             the top of the activity stack, with user input going to it.
348 *             <p>Always followed by <code>onPause()</code>.</td>
349 *         <td align="center">No</td>
350 *         <td align="center"><code>onPause()</code></td>
351 *     </tr>
352 *
353 *     <tr><td align="left" border="0">{@link android.app.Activity#onPause onPause()}</td>
354 *         <td>Called when the system is about to start resuming a previous
355 *             activity.  This is typically used to commit unsaved changes to
356 *             persistent data, stop animations and other things that may be consuming
357 *             CPU, etc.  Implementations of this method must be very quick because
358 *             the next activity will not be resumed until this method returns.
359 *             <p>Followed by either <code>onResume()</code> if the activity
360 *             returns back to the front, or <code>onStop()</code> if it becomes
361 *             invisible to the user.</td>
362 *         <td align="center"><font color="#800000"><strong>Pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB}</strong></font></td>
363 *         <td align="center"><code>onResume()</code> or<br>
364 *                 <code>onStop()</code></td>
365 *     </tr>
366 *
367 *     <tr><td colspan="2" align="left" border="0">{@link android.app.Activity#onStop onStop()}</td>
368 *         <td>Called when the activity is no longer visible to the user, because
369 *             another activity has been resumed and is covering this one.  This
370 *             may happen either because a new activity is being started, an existing
371 *             one is being brought in front of this one, or this one is being
372 *             destroyed.
373 *             <p>Followed by either <code>onRestart()</code> if
374 *             this activity is coming back to interact with the user, or
375 *             <code>onDestroy()</code> if this activity is going away.</td>
376 *         <td align="center"><font color="#800000"><strong>Yes</strong></font></td>
377 *         <td align="center"><code>onRestart()</code> or<br>
378 *                 <code>onDestroy()</code></td>
379 *     </tr>
380 *
381 *     <tr><td colspan="3" align="left" border="0">{@link android.app.Activity#onDestroy onDestroy()}</td>
382 *         <td>The final call you receive before your
383 *             activity is destroyed.  This can happen either because the
384 *             activity is finishing (someone called {@link Activity#finish} on
385 *             it, or because the system is temporarily destroying this
386 *             instance of the activity to save space.  You can distinguish
387 *             between these two scenarios with the {@link
388 *             Activity#isFinishing} method.</td>
389 *         <td align="center"><font color="#800000"><strong>Yes</strong></font></td>
390 *         <td align="center"><em>nothing</em></td>
391 *     </tr>
392 *     </tbody>
393 * </table>
394 *
395 * <p>Note the "Killable" column in the above table -- for those methods that
396 * are marked as being killable, after that method returns the process hosting the
397 * activity may be killed by the system <em>at any time</em> without another line
398 * of its code being executed.  Because of this, you should use the
399 * {@link #onPause} method to write any persistent data (such as user edits)
400 * to storage.  In addition, the method
401 * {@link #onSaveInstanceState(Bundle)} is called before placing the activity
402 * in such a background state, allowing you to save away any dynamic instance
403 * state in your activity into the given Bundle, to be later received in
404 * {@link #onCreate} if the activity needs to be re-created.
405 * See the <a href="#ProcessLifecycle">Process Lifecycle</a>
406 * section for more information on how the lifecycle of a process is tied
407 * to the activities it is hosting.  Note that it is important to save
408 * persistent data in {@link #onPause} instead of {@link #onSaveInstanceState}
409 * because the latter is not part of the lifecycle callbacks, so will not
410 * be called in every situation as described in its documentation.</p>
411 *
412 * <p class="note">Be aware that these semantics will change slightly between
413 * applications targeting platforms starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB}
414 * vs. those targeting prior platforms.  Starting with Honeycomb, an application
415 * is not in the killable state until its {@link #onStop} has returned.  This
416 * impacts when {@link #onSaveInstanceState(Bundle)} may be called (it may be
417 * safely called after {@link #onPause()} and allows and application to safely
418 * wait until {@link #onStop()} to save persistent state.</p>
419 *
420 * <p>For those methods that are not marked as being killable, the activity's
421 * process will not be killed by the system starting from the time the method
422 * is called and continuing after it returns.  Thus an activity is in the killable
423 * state, for example, between after <code>onPause()</code> to the start of
424 * <code>onResume()</code>.</p>
425 *
426 * <a name="ConfigurationChanges"></a>
427 * <h3>Configuration Changes</h3>
428 *
429 * <p>If the configuration of the device (as defined by the
430 * {@link Configuration Resources.Configuration} class) changes,
431 * then anything displaying a user interface will need to update to match that
432 * configuration.  Because Activity is the primary mechanism for interacting
433 * with the user, it includes special support for handling configuration
434 * changes.</p>
435 *
436 * <p>Unless you specify otherwise, a configuration change (such as a change
437 * in screen orientation, language, input devices, etc) will cause your
438 * current activity to be <em>destroyed</em>, going through the normal activity
439 * lifecycle process of {@link #onPause},
440 * {@link #onStop}, and {@link #onDestroy} as appropriate.  If the activity
441 * had been in the foreground or visible to the user, once {@link #onDestroy} is
442 * called in that instance then a new instance of the activity will be
443 * created, with whatever savedInstanceState the previous instance had generated
444 * from {@link #onSaveInstanceState}.</p>
445 *
446 * <p>This is done because any application resource,
447 * including layout files, can change based on any configuration value.  Thus
448 * the only safe way to handle a configuration change is to re-retrieve all
449 * resources, including layouts, drawables, and strings.  Because activities
450 * must already know how to save their state and re-create themselves from
451 * that state, this is a convenient way to have an activity restart itself
452 * with a new configuration.</p>
453 *
454 * <p>In some special cases, you may want to bypass restarting of your
455 * activity based on one or more types of configuration changes.  This is
456 * done with the {@link android.R.attr#configChanges android:configChanges}
457 * attribute in its manifest.  For any types of configuration changes you say
458 * that you handle there, you will receive a call to your current activity's
459 * {@link #onConfigurationChanged} method instead of being restarted.  If
460 * a configuration change involves any that you do not handle, however, the
461 * activity will still be restarted and {@link #onConfigurationChanged}
462 * will not be called.</p>
463 *
464 * <a name="StartingActivities"></a>
465 * <h3>Starting Activities and Getting Results</h3>
466 *
467 * <p>The {@link android.app.Activity#startActivity}
468 * method is used to start a
469 * new activity, which will be placed at the top of the activity stack.  It
470 * takes a single argument, an {@link android.content.Intent Intent},
471 * which describes the activity
472 * to be executed.</p>
473 *
474 * <p>Sometimes you want to get a result back from an activity when it
475 * ends.  For example, you may start an activity that lets the user pick
476 * a person in a list of contacts; when it ends, it returns the person
477 * that was selected.  To do this, you call the
478 * {@link android.app.Activity#startActivityForResult(Intent, int)}
479 * version with a second integer parameter identifying the call.  The result
480 * will come back through your {@link android.app.Activity#onActivityResult}
481 * method.</p>
482 *
483 * <p>When an activity exits, it can call
484 * {@link android.app.Activity#setResult(int)}
485 * to return data back to its parent.  It must always supply a result code,
486 * which can be the standard results RESULT_CANCELED, RESULT_OK, or any
487 * custom values starting at RESULT_FIRST_USER.  In addition, it can optionally
488 * return back an Intent containing any additional data it wants.  All of this
489 * information appears back on the
490 * parent's <code>Activity.onActivityResult()</code>, along with the integer
491 * identifier it originally supplied.</p>
492 *
493 * <p>If a child activity fails for any reason (such as crashing), the parent
494 * activity will receive a result with the code RESULT_CANCELED.</p>
495 *
496 * <pre class="prettyprint">
497 * public class MyActivity extends Activity {
498 *     ...
499 *
500 *     static final int PICK_CONTACT_REQUEST = 0;
501 *
502 *     public boolean onKeyDown(int keyCode, KeyEvent event) {
503 *         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
504 *             // When the user center presses, let them pick a contact.
505 *             startActivityForResult(
506 *                 new Intent(Intent.ACTION_PICK,
507 *                 new Uri("content://contacts")),
508 *                 PICK_CONTACT_REQUEST);
509 *            return true;
510 *         }
511 *         return false;
512 *     }
513 *
514 *     protected void onActivityResult(int requestCode, int resultCode,
515 *             Intent data) {
516 *         if (requestCode == PICK_CONTACT_REQUEST) {
517 *             if (resultCode == RESULT_OK) {
518 *                 // A contact was picked.  Here we will just display it
519 *                 // to the user.
520 *                 startActivity(new Intent(Intent.ACTION_VIEW, data));
521 *             }
522 *         }
523 *     }
524 * }
525 * </pre>
526 *
527 * <a name="SavingPersistentState"></a>
528 * <h3>Saving Persistent State</h3>
529 *
530 * <p>There are generally two kinds of persistent state than an activity
531 * will deal with: shared document-like data (typically stored in a SQLite
532 * database using a {@linkplain android.content.ContentProvider content provider})
533 * and internal state such as user preferences.</p>
534 *
535 * <p>For content provider data, we suggest that activities use a
536 * "edit in place" user model.  That is, any edits a user makes are effectively
537 * made immediately without requiring an additional confirmation step.
538 * Supporting this model is generally a simple matter of following two rules:</p>
539 *
540 * <ul>
541 *     <li> <p>When creating a new document, the backing database entry or file for
542 *             it is created immediately.  For example, if the user chooses to write
543 *             a new e-mail, a new entry for that e-mail is created as soon as they
544 *             start entering data, so that if they go to any other activity after
545 *             that point this e-mail will now appear in the list of drafts.</p>
546 *     <li> <p>When an activity's <code>onPause()</code> method is called, it should
547 *             commit to the backing content provider or file any changes the user
548 *             has made.  This ensures that those changes will be seen by any other
549 *             activity that is about to run.  You will probably want to commit
550 *             your data even more aggressively at key times during your
551 *             activity's lifecycle: for example before starting a new
552 *             activity, before finishing your own activity, when the user
553 *             switches between input fields, etc.</p>
554 * </ul>
555 *
556 * <p>This model is designed to prevent data loss when a user is navigating
557 * between activities, and allows the system to safely kill an activity (because
558 * system resources are needed somewhere else) at any time after it has been
559 * paused.  Note this implies
560 * that the user pressing BACK from your activity does <em>not</em>
561 * mean "cancel" -- it means to leave the activity with its current contents
562 * saved away.  Canceling edits in an activity must be provided through
563 * some other mechanism, such as an explicit "revert" or "undo" option.</p>
564 *
565 * <p>See the {@linkplain android.content.ContentProvider content package} for
566 * more information about content providers.  These are a key aspect of how
567 * different activities invoke and propagate data between themselves.</p>
568 *
569 * <p>The Activity class also provides an API for managing internal persistent state
570 * associated with an activity.  This can be used, for example, to remember
571 * the user's preferred initial display in a calendar (day view or week view)
572 * or the user's default home page in a web browser.</p>
573 *
574 * <p>Activity persistent state is managed
575 * with the method {@link #getPreferences},
576 * allowing you to retrieve and
577 * modify a set of name/value pairs associated with the activity.  To use
578 * preferences that are shared across multiple application components
579 * (activities, receivers, services, providers), you can use the underlying
580 * {@link Context#getSharedPreferences Context.getSharedPreferences()} method
581 * to retrieve a preferences
582 * object stored under a specific name.
583 * (Note that it is not possible to share settings data across application
584 * packages -- for that you will need a content provider.)</p>
585 *
586 * <p>Here is an excerpt from a calendar activity that stores the user's
587 * preferred view mode in its persistent settings:</p>
588 *
589 * <pre class="prettyprint">
590 * public class CalendarActivity extends Activity {
591 *     ...
592 *
593 *     static final int DAY_VIEW_MODE = 0;
594 *     static final int WEEK_VIEW_MODE = 1;
595 *
596 *     private SharedPreferences mPrefs;
597 *     private int mCurViewMode;
598 *
599 *     protected void onCreate(Bundle savedInstanceState) {
600 *         super.onCreate(savedInstanceState);
601 *
602 *         SharedPreferences mPrefs = getSharedPreferences();
603 *         mCurViewMode = mPrefs.getInt("view_mode", DAY_VIEW_MODE);
604 *     }
605 *
606 *     protected void onPause() {
607 *         super.onPause();
608 *
609 *         SharedPreferences.Editor ed = mPrefs.edit();
610 *         ed.putInt("view_mode", mCurViewMode);
611 *         ed.commit();
612 *     }
613 * }
614 * </pre>
615 *
616 * <a name="Permissions"></a>
617 * <h3>Permissions</h3>
618 *
619 * <p>The ability to start a particular Activity can be enforced when it is
620 * declared in its
621 * manifest's {@link android.R.styleable#AndroidManifestActivity &lt;activity&gt;}
622 * tag.  By doing so, other applications will need to declare a corresponding
623 * {@link android.R.styleable#AndroidManifestUsesPermission &lt;uses-permission&gt;}
624 * element in their own manifest to be able to start that activity.
625 *
626 * <p>When starting an Activity you can set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
627 * Intent.FLAG_GRANT_READ_URI_PERMISSION} and/or {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION
628 * Intent.FLAG_GRANT_WRITE_URI_PERMISSION} on the Intent.  This will grant the
629 * Activity access to the specific URIs in the Intent.  Access will remain
630 * until the Activity has finished (it will remain across the hosting
631 * process being killed and other temporary destruction).  As of
632 * {@link android.os.Build.VERSION_CODES#GINGERBREAD}, if the Activity
633 * was already created and a new Intent is being delivered to
634 * {@link #onNewIntent(Intent)}, any newly granted URI permissions will be added
635 * to the existing ones it holds.
636 *
637 * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>
638 * document for more information on permissions and security in general.
639 *
640 * <a name="ProcessLifecycle"></a>
641 * <h3>Process Lifecycle</h3>
642 *
643 * <p>The Android system attempts to keep application process around for as
644 * long as possible, but eventually will need to remove old processes when
645 * memory runs low.  As described in <a href="#ActivityLifecycle">Activity
646 * Lifecycle</a>, the decision about which process to remove is intimately
647 * tied to the state of the user's interaction with it.  In general, there
648 * are four states a process can be in based on the activities running in it,
649 * listed here in order of importance.  The system will kill less important
650 * processes (the last ones) before it resorts to killing more important
651 * processes (the first ones).
652 *
653 * <ol>
654 * <li> <p>The <b>foreground activity</b> (the activity at the top of the screen
655 * that the user is currently interacting with) is considered the most important.
656 * Its process will only be killed as a last resort, if it uses more memory
657 * than is available on the device.  Generally at this point the device has
658 * reached a memory paging state, so this is required in order to keep the user
659 * interface responsive.
660 * <li> <p>A <b>visible activity</b> (an activity that is visible to the user
661 * but not in the foreground, such as one sitting behind a foreground dialog)
662 * is considered extremely important and will not be killed unless that is
663 * required to keep the foreground activity running.
664 * <li> <p>A <b>background activity</b> (an activity that is not visible to
665 * the user and has been paused) is no longer critical, so the system may
666 * safely kill its process to reclaim memory for other foreground or
667 * visible processes.  If its process needs to be killed, when the user navigates
668 * back to the activity (making it visible on the screen again), its
669 * {@link #onCreate} method will be called with the savedInstanceState it had previously
670 * supplied in {@link #onSaveInstanceState} so that it can restart itself in the same
671 * state as the user last left it.
672 * <li> <p>An <b>empty process</b> is one hosting no activities or other
673 * application components (such as {@link Service} or
674 * {@link android.content.BroadcastReceiver} classes).  These are killed very
675 * quickly by the system as memory becomes low.  For this reason, any
676 * background operation you do outside of an activity must be executed in the
677 * context of an activity BroadcastReceiver or Service to ensure that the system
678 * knows it needs to keep your process around.
679 * </ol>
680 *
681 * <p>Sometimes an Activity may need to do a long-running operation that exists
682 * independently of the activity lifecycle itself.  An example may be a camera
683 * application that allows you to upload a picture to a web site.  The upload
684 * may take a long time, and the application should allow the user to leave
685 * the application while it is executing.  To accomplish this, your Activity
686 * should start a {@link Service} in which the upload takes place.  This allows
687 * the system to properly prioritize your process (considering it to be more
688 * important than other non-visible applications) for the duration of the
689 * upload, independent of whether the original activity is paused, stopped,
690 * or finished.
691 */
692public class Activity extends ContextThemeWrapper
693        implements LayoutInflater.Factory2,
694        Window.Callback, KeyEvent.Callback,
695        OnCreateContextMenuListener, ComponentCallbacks2,
696        Window.OnWindowDismissedCallback, WindowControllerCallback,
697        AutofillManager.AutofillClient {
698    private static final String TAG = "Activity";
699    private static final boolean DEBUG_LIFECYCLE = false;
700
701    /** Standard activity result: operation canceled. */
702    public static final int RESULT_CANCELED    = 0;
703    /** Standard activity result: operation succeeded. */
704    public static final int RESULT_OK           = -1;
705    /** Start of user-defined activity results. */
706    public static final int RESULT_FIRST_USER   = 1;
707
708    /** @hide Task isn't finished when activity is finished */
709    public static final int DONT_FINISH_TASK_WITH_ACTIVITY = 0;
710    /**
711     * @hide Task is finished if the finishing activity is the root of the task. To preserve the
712     * past behavior the task is also removed from recents.
713     */
714    public static final int FINISH_TASK_WITH_ROOT_ACTIVITY = 1;
715    /**
716     * @hide Task is finished along with the finishing activity, but it is not removed from
717     * recents.
718     */
719    public static final int FINISH_TASK_WITH_ACTIVITY = 2;
720
721    static final String FRAGMENTS_TAG = "android:fragments";
722    private static final String LAST_ACCESSIBILITY_ID = "android:lastAccessibilityId";
723
724    private static final String AUTOFILL_RESET_NEEDED = "@android:autofillResetNeeded";
725    private static final String WINDOW_HIERARCHY_TAG = "android:viewHierarchyState";
726    private static final String SAVED_DIALOG_IDS_KEY = "android:savedDialogIds";
727    private static final String SAVED_DIALOGS_TAG = "android:savedDialogs";
728    private static final String SAVED_DIALOG_KEY_PREFIX = "android:dialog_";
729    private static final String SAVED_DIALOG_ARGS_KEY_PREFIX = "android:dialog_args_";
730    private static final String HAS_CURENT_PERMISSIONS_REQUEST_KEY =
731            "android:hasCurrentPermissionsRequest";
732
733    private static final String REQUEST_PERMISSIONS_WHO_PREFIX = "@android:requestPermissions:";
734    private static final String AUTO_FILL_AUTH_WHO_PREFIX = "@android:autoFillAuth:";
735
736    private static final String KEYBOARD_SHORTCUTS_RECEIVER_PKG_NAME = "com.android.systemui";
737
738    private static class ManagedDialog {
739        Dialog mDialog;
740        Bundle mArgs;
741    }
742    private SparseArray<ManagedDialog> mManagedDialogs;
743
744    // set by the thread after the constructor and before onCreate(Bundle savedInstanceState) is called.
745    private Instrumentation mInstrumentation;
746    private IBinder mToken;
747    private int mIdent;
748    /*package*/ String mEmbeddedID;
749    private Application mApplication;
750    /*package*/ Intent mIntent;
751    /*package*/ String mReferrer;
752    private ComponentName mComponent;
753    /*package*/ ActivityInfo mActivityInfo;
754    /*package*/ ActivityThread mMainThread;
755    Activity mParent;
756    boolean mCalled;
757    /*package*/ boolean mResumed;
758    /*package*/ boolean mStopped;
759    boolean mFinished;
760    boolean mStartedActivity;
761    private boolean mDestroyed;
762    private boolean mDoReportFullyDrawn = true;
763    /** true if the activity is going through a transient pause */
764    /*package*/ boolean mTemporaryPause = false;
765    /** true if the activity is being destroyed in order to recreate it with a new configuration */
766    /*package*/ boolean mChangingConfigurations = false;
767    /*package*/ int mConfigChangeFlags;
768    /*package*/ Configuration mCurrentConfig;
769    private SearchManager mSearchManager;
770    private MenuInflater mMenuInflater;
771
772    /** The autofill manager. Always access via {@link #getAutofillManager()}. */
773    @Nullable private AutofillManager mAutofillManager;
774
775    static final class NonConfigurationInstances {
776        Object activity;
777        HashMap<String, Object> children;
778        FragmentManagerNonConfig fragments;
779        ArrayMap<String, LoaderManager> loaders;
780        VoiceInteractor voiceInteractor;
781    }
782    /* package */ NonConfigurationInstances mLastNonConfigurationInstances;
783
784    private Window mWindow;
785
786    private WindowManager mWindowManager;
787    /*package*/ View mDecor = null;
788    /*package*/ boolean mWindowAdded = false;
789    /*package*/ boolean mVisibleFromServer = false;
790    /*package*/ boolean mVisibleFromClient = true;
791    /*package*/ ActionBar mActionBar = null;
792    private boolean mEnableDefaultActionBarUp;
793
794    private VoiceInteractor mVoiceInteractor;
795
796    private CharSequence mTitle;
797    private int mTitleColor = 0;
798
799    // we must have a handler before the FragmentController is constructed
800    final Handler mHandler = new Handler();
801    final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
802
803    // Most recent call to requestVisibleBehind().
804    @Deprecated
805    boolean mVisibleBehind;
806
807    private static final class ManagedCursor {
808        ManagedCursor(Cursor cursor) {
809            mCursor = cursor;
810            mReleased = false;
811            mUpdated = false;
812        }
813
814        private final Cursor mCursor;
815        private boolean mReleased;
816        private boolean mUpdated;
817    }
818
819    @GuardedBy("mManagedCursors")
820    private final ArrayList<ManagedCursor> mManagedCursors = new ArrayList<>();
821
822    @GuardedBy("this")
823    int mResultCode = RESULT_CANCELED;
824    @GuardedBy("this")
825    Intent mResultData = null;
826
827    private TranslucentConversionListener mTranslucentCallback;
828    private boolean mChangeCanvasToTranslucent;
829
830    private SearchEvent mSearchEvent;
831
832    private boolean mTitleReady = false;
833    private int mActionModeTypeStarting = ActionMode.TYPE_PRIMARY;
834
835    private int mDefaultKeyMode = DEFAULT_KEYS_DISABLE;
836    private SpannableStringBuilder mDefaultKeySsb = null;
837
838    private ActivityManager.TaskDescription mTaskDescription =
839            new ActivityManager.TaskDescription();
840
841    protected static final int[] FOCUSED_STATE_SET = {com.android.internal.R.attr.state_focused};
842
843    @SuppressWarnings("unused")
844    private final Object mInstanceTracker = StrictMode.trackActivity(this);
845
846    private Thread mUiThread;
847
848    ActivityTransitionState mActivityTransitionState = new ActivityTransitionState();
849    SharedElementCallback mEnterTransitionListener = SharedElementCallback.NULL_CALLBACK;
850    SharedElementCallback mExitTransitionListener = SharedElementCallback.NULL_CALLBACK;
851
852    private boolean mHasCurrentPermissionsRequest;
853
854    private boolean mAutoFillResetNeeded;
855
856    /** The last accessibility id that was returned from {@link #getNextAccessibilityId()} */
857    private int mLastAccessibilityId = View.LAST_APP_ACCESSIBILITY_ID;
858
859    private AutofillPopupWindow mAutofillPopupWindow;
860
861    private static native String getDlWarning();
862
863    /** Return the intent that started this activity. */
864    public Intent getIntent() {
865        return mIntent;
866    }
867
868    /**
869     * Change the intent returned by {@link #getIntent}.  This holds a
870     * reference to the given intent; it does not copy it.  Often used in
871     * conjunction with {@link #onNewIntent}.
872     *
873     * @param newIntent The new Intent object to return from getIntent
874     *
875     * @see #getIntent
876     * @see #onNewIntent
877     */
878    public void setIntent(Intent newIntent) {
879        mIntent = newIntent;
880    }
881
882    /** Return the application that owns this activity. */
883    public final Application getApplication() {
884        return mApplication;
885    }
886
887    /** Is this activity embedded inside of another activity? */
888    public final boolean isChild() {
889        return mParent != null;
890    }
891
892    /** Return the parent activity if this view is an embedded child. */
893    public final Activity getParent() {
894        return mParent;
895    }
896
897    /** Retrieve the window manager for showing custom windows. */
898    public WindowManager getWindowManager() {
899        return mWindowManager;
900    }
901
902    /**
903     * Retrieve the current {@link android.view.Window} for the activity.
904     * This can be used to directly access parts of the Window API that
905     * are not available through Activity/Screen.
906     *
907     * @return Window The current window, or null if the activity is not
908     *         visual.
909     */
910    public Window getWindow() {
911        return mWindow;
912    }
913
914    /**
915     * Return the LoaderManager for this activity, creating it if needed.
916     */
917    public LoaderManager getLoaderManager() {
918        return mFragments.getLoaderManager();
919    }
920
921    /**
922     * Calls {@link android.view.Window#getCurrentFocus} on the
923     * Window of this Activity to return the currently focused view.
924     *
925     * @return View The current View with focus or null.
926     *
927     * @see #getWindow
928     * @see android.view.Window#getCurrentFocus
929     */
930    @Nullable
931    public View getCurrentFocus() {
932        return mWindow != null ? mWindow.getCurrentFocus() : null;
933    }
934
935    /**
936     * (Create and) return the autofill manager
937     *
938     * @return The autofill manager
939     */
940    @NonNull private AutofillManager getAutofillManager() {
941        if (mAutofillManager == null) {
942            mAutofillManager = getSystemService(AutofillManager.class);
943        }
944
945        return mAutofillManager;
946    }
947
948    /**
949     * Called when the activity is starting.  This is where most initialization
950     * should go: calling {@link #setContentView(int)} to inflate the
951     * activity's UI, using {@link #findViewById} to programmatically interact
952     * with widgets in the UI, calling
953     * {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve
954     * cursors for data being displayed, etc.
955     *
956     * <p>You can call {@link #finish} from within this function, in
957     * which case onDestroy() will be immediately called without any of the rest
958     * of the activity lifecycle ({@link #onStart}, {@link #onResume},
959     * {@link #onPause}, etc) executing.
960     *
961     * <p><em>Derived classes must call through to the super class's
962     * implementation of this method.  If they do not, an exception will be
963     * thrown.</em></p>
964     *
965     * @param savedInstanceState If the activity is being re-initialized after
966     *     previously being shut down then this Bundle contains the data it most
967     *     recently supplied in {@link #onSaveInstanceState}.  <b><i>Note: Otherwise it is null.</i></b>
968     *
969     * @see #onStart
970     * @see #onSaveInstanceState
971     * @see #onRestoreInstanceState
972     * @see #onPostCreate
973     */
974    @MainThread
975    @CallSuper
976    protected void onCreate(@Nullable Bundle savedInstanceState) {
977        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
978
979        if (getApplicationInfo().targetSdkVersion >= O && mActivityInfo.isFixedOrientation()) {
980            final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
981            final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
982            ta.recycle();
983
984            if (isTranslucentOrFloating) {
985                throw new IllegalStateException(
986                        "Only fullscreen opaque activities can request orientation");
987            }
988        }
989
990        if (mLastNonConfigurationInstances != null) {
991            mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
992        }
993        if (mActivityInfo.parentActivityName != null) {
994            if (mActionBar == null) {
995                mEnableDefaultActionBarUp = true;
996            } else {
997                mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
998            }
999        }
1000        if (savedInstanceState != null) {
1001            mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
1002            mLastAccessibilityId = savedInstanceState.getInt(LAST_ACCESSIBILITY_ID, View.NO_ID);
1003
1004            if (mAutoFillResetNeeded) {
1005                getAutofillManager().onCreate(savedInstanceState);
1006            }
1007
1008            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
1009            mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
1010                    ? mLastNonConfigurationInstances.fragments : null);
1011        }
1012        mFragments.dispatchCreate();
1013        getApplication().dispatchActivityCreated(this, savedInstanceState);
1014        if (mVoiceInteractor != null) {
1015            mVoiceInteractor.attachActivity(this);
1016        }
1017        mCalled = true;
1018    }
1019
1020    /**
1021     * Same as {@link #onCreate(android.os.Bundle)} but called for those activities created with
1022     * the attribute {@link android.R.attr#persistableMode} set to
1023     * <code>persistAcrossReboots</code>.
1024     *
1025     * @param savedInstanceState if the activity is being re-initialized after
1026     *     previously being shut down then this Bundle contains the data it most
1027     *     recently supplied in {@link #onSaveInstanceState}.
1028     *     <b><i>Note: Otherwise it is null.</i></b>
1029     * @param persistentState if the activity is being re-initialized after
1030     *     previously being shut down or powered off then this Bundle contains the data it most
1031     *     recently supplied to outPersistentState in {@link #onSaveInstanceState}.
1032     *     <b><i>Note: Otherwise it is null.</i></b>
1033     *
1034     * @see #onCreate(android.os.Bundle)
1035     * @see #onStart
1036     * @see #onSaveInstanceState
1037     * @see #onRestoreInstanceState
1038     * @see #onPostCreate
1039     */
1040    public void onCreate(@Nullable Bundle savedInstanceState,
1041            @Nullable PersistableBundle persistentState) {
1042        onCreate(savedInstanceState);
1043    }
1044
1045    /**
1046     * The hook for {@link ActivityThread} to restore the state of this activity.
1047     *
1048     * Calls {@link #onSaveInstanceState(android.os.Bundle)} and
1049     * {@link #restoreManagedDialogs(android.os.Bundle)}.
1050     *
1051     * @param savedInstanceState contains the saved state
1052     */
1053    final void performRestoreInstanceState(Bundle savedInstanceState) {
1054        onRestoreInstanceState(savedInstanceState);
1055        restoreManagedDialogs(savedInstanceState);
1056    }
1057
1058    /**
1059     * The hook for {@link ActivityThread} to restore the state of this activity.
1060     *
1061     * Calls {@link #onSaveInstanceState(android.os.Bundle)} and
1062     * {@link #restoreManagedDialogs(android.os.Bundle)}.
1063     *
1064     * @param savedInstanceState contains the saved state
1065     * @param persistentState contains the persistable saved state
1066     */
1067    final void performRestoreInstanceState(Bundle savedInstanceState,
1068            PersistableBundle persistentState) {
1069        onRestoreInstanceState(savedInstanceState, persistentState);
1070        if (savedInstanceState != null) {
1071            restoreManagedDialogs(savedInstanceState);
1072        }
1073    }
1074
1075    /**
1076     * This method is called after {@link #onStart} when the activity is
1077     * being re-initialized from a previously saved state, given here in
1078     * <var>savedInstanceState</var>.  Most implementations will simply use {@link #onCreate}
1079     * to restore their state, but it is sometimes convenient to do it here
1080     * after all of the initialization has been done or to allow subclasses to
1081     * decide whether to use your default implementation.  The default
1082     * implementation of this method performs a restore of any view state that
1083     * had previously been frozen by {@link #onSaveInstanceState}.
1084     *
1085     * <p>This method is called between {@link #onStart} and
1086     * {@link #onPostCreate}.
1087     *
1088     * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}.
1089     *
1090     * @see #onCreate
1091     * @see #onPostCreate
1092     * @see #onResume
1093     * @see #onSaveInstanceState
1094     */
1095    protected void onRestoreInstanceState(Bundle savedInstanceState) {
1096        if (mWindow != null) {
1097            Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG);
1098            if (windowState != null) {
1099                mWindow.restoreHierarchyState(windowState);
1100            }
1101        }
1102    }
1103
1104    /**
1105     * This is the same as {@link #onRestoreInstanceState(Bundle)} but is called for activities
1106     * created with the attribute {@link android.R.attr#persistableMode} set to
1107     * <code>persistAcrossReboots</code>. The {@link android.os.PersistableBundle} passed
1108     * came from the restored PersistableBundle first
1109     * saved in {@link #onSaveInstanceState(Bundle, PersistableBundle)}.
1110     *
1111     * <p>This method is called between {@link #onStart} and
1112     * {@link #onPostCreate}.
1113     *
1114     * <p>If this method is called {@link #onRestoreInstanceState(Bundle)} will not be called.
1115     *
1116     * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}.
1117     * @param persistentState the data most recently supplied in {@link #onSaveInstanceState}.
1118     *
1119     * @see #onRestoreInstanceState(Bundle)
1120     * @see #onCreate
1121     * @see #onPostCreate
1122     * @see #onResume
1123     * @see #onSaveInstanceState
1124     */
1125    public void onRestoreInstanceState(Bundle savedInstanceState,
1126            PersistableBundle persistentState) {
1127        if (savedInstanceState != null) {
1128            onRestoreInstanceState(savedInstanceState);
1129        }
1130    }
1131
1132    /**
1133     * Restore the state of any saved managed dialogs.
1134     *
1135     * @param savedInstanceState The bundle to restore from.
1136     */
1137    private void restoreManagedDialogs(Bundle savedInstanceState) {
1138        final Bundle b = savedInstanceState.getBundle(SAVED_DIALOGS_TAG);
1139        if (b == null) {
1140            return;
1141        }
1142
1143        final int[] ids = b.getIntArray(SAVED_DIALOG_IDS_KEY);
1144        final int numDialogs = ids.length;
1145        mManagedDialogs = new SparseArray<ManagedDialog>(numDialogs);
1146        for (int i = 0; i < numDialogs; i++) {
1147            final Integer dialogId = ids[i];
1148            Bundle dialogState = b.getBundle(savedDialogKeyFor(dialogId));
1149            if (dialogState != null) {
1150                // Calling onRestoreInstanceState() below will invoke dispatchOnCreate
1151                // so tell createDialog() not to do it, otherwise we get an exception
1152                final ManagedDialog md = new ManagedDialog();
1153                md.mArgs = b.getBundle(savedDialogArgsKeyFor(dialogId));
1154                md.mDialog = createDialog(dialogId, dialogState, md.mArgs);
1155                if (md.mDialog != null) {
1156                    mManagedDialogs.put(dialogId, md);
1157                    onPrepareDialog(dialogId, md.mDialog, md.mArgs);
1158                    md.mDialog.onRestoreInstanceState(dialogState);
1159                }
1160            }
1161        }
1162    }
1163
1164    private Dialog createDialog(Integer dialogId, Bundle state, Bundle args) {
1165        final Dialog dialog = onCreateDialog(dialogId, args);
1166        if (dialog == null) {
1167            return null;
1168        }
1169        dialog.dispatchOnCreate(state);
1170        return dialog;
1171    }
1172
1173    private static String savedDialogKeyFor(int key) {
1174        return SAVED_DIALOG_KEY_PREFIX + key;
1175    }
1176
1177    private static String savedDialogArgsKeyFor(int key) {
1178        return SAVED_DIALOG_ARGS_KEY_PREFIX + key;
1179    }
1180
1181    /**
1182     * Called when activity start-up is complete (after {@link #onStart}
1183     * and {@link #onRestoreInstanceState} have been called).  Applications will
1184     * generally not implement this method; it is intended for system
1185     * classes to do final initialization after application code has run.
1186     *
1187     * <p><em>Derived classes must call through to the super class's
1188     * implementation of this method.  If they do not, an exception will be
1189     * thrown.</em></p>
1190     *
1191     * @param savedInstanceState If the activity is being re-initialized after
1192     *     previously being shut down then this Bundle contains the data it most
1193     *     recently supplied in {@link #onSaveInstanceState}.  <b><i>Note: Otherwise it is null.</i></b>
1194     * @see #onCreate
1195     */
1196    @CallSuper
1197    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
1198        if (!isChild()) {
1199            mTitleReady = true;
1200            onTitleChanged(getTitle(), getTitleColor());
1201        }
1202
1203        mCalled = true;
1204    }
1205
1206    /**
1207     * This is the same as {@link #onPostCreate(Bundle)} but is called for activities
1208     * created with the attribute {@link android.R.attr#persistableMode} set to
1209     * <code>persistAcrossReboots</code>.
1210     *
1211     * @param savedInstanceState The data most recently supplied in {@link #onSaveInstanceState}
1212     * @param persistentState The data caming from the PersistableBundle first
1213     * saved in {@link #onSaveInstanceState(Bundle, PersistableBundle)}.
1214     *
1215     * @see #onCreate
1216     */
1217    public void onPostCreate(@Nullable Bundle savedInstanceState,
1218            @Nullable PersistableBundle persistentState) {
1219        onPostCreate(savedInstanceState);
1220    }
1221
1222    /**
1223     * Called after {@link #onCreate} &mdash; or after {@link #onRestart} when
1224     * the activity had been stopped, but is now again being displayed to the
1225     * user.  It will be followed by {@link #onResume}.
1226     *
1227     * <p><em>Derived classes must call through to the super class's
1228     * implementation of this method.  If they do not, an exception will be
1229     * thrown.</em></p>
1230     *
1231     * @see #onCreate
1232     * @see #onStop
1233     * @see #onResume
1234     */
1235    @CallSuper
1236    protected void onStart() {
1237        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this);
1238        mCalled = true;
1239
1240        mFragments.doLoaderStart();
1241
1242        getApplication().dispatchActivityStarted(this);
1243
1244        if (mAutoFillResetNeeded) {
1245            AutofillManager afm = getAutofillManager();
1246            if (afm != null) {
1247                afm.onVisibleForAutofill();
1248            }
1249        }
1250    }
1251
1252    /**
1253     * Called after {@link #onStop} when the current activity is being
1254     * re-displayed to the user (the user has navigated back to it).  It will
1255     * be followed by {@link #onStart} and then {@link #onResume}.
1256     *
1257     * <p>For activities that are using raw {@link Cursor} objects (instead of
1258     * creating them through
1259     * {@link #managedQuery(android.net.Uri , String[], String, String[], String)},
1260     * this is usually the place
1261     * where the cursor should be requeried (because you had deactivated it in
1262     * {@link #onStop}.
1263     *
1264     * <p><em>Derived classes must call through to the super class's
1265     * implementation of this method.  If they do not, an exception will be
1266     * thrown.</em></p>
1267     *
1268     * @see #onStop
1269     * @see #onStart
1270     * @see #onResume
1271     */
1272    @CallSuper
1273    protected void onRestart() {
1274        mCalled = true;
1275    }
1276
1277    /**
1278     * Called when an {@link #onResume} is coming up, prior to other pre-resume callbacks
1279     * such as {@link #onNewIntent} and {@link #onActivityResult}.  This is primarily intended
1280     * to give the activity a hint that its state is no longer saved -- it will generally
1281     * be called after {@link #onSaveInstanceState} and prior to the activity being
1282     * resumed/started again.
1283     */
1284    public void onStateNotSaved() {
1285    }
1286
1287    /**
1288     * Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or
1289     * {@link #onPause}, for your activity to start interacting with the user.
1290     * This is a good place to begin animations, open exclusive-access devices
1291     * (such as the camera), etc.
1292     *
1293     * <p>Keep in mind that onResume is not the best indicator that your activity
1294     * is visible to the user; a system window such as the keyguard may be in
1295     * front.  Use {@link #onWindowFocusChanged} to know for certain that your
1296     * activity is visible to the user (for example, to resume a game).
1297     *
1298     * <p><em>Derived classes must call through to the super class's
1299     * implementation of this method.  If they do not, an exception will be
1300     * thrown.</em></p>
1301     *
1302     * @see #onRestoreInstanceState
1303     * @see #onRestart
1304     * @see #onPostResume
1305     * @see #onPause
1306     */
1307    @CallSuper
1308    protected void onResume() {
1309        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
1310        getApplication().dispatchActivityResumed(this);
1311        mActivityTransitionState.onResume(this, isTopOfTask());
1312        mCalled = true;
1313    }
1314
1315    /**
1316     * Called when activity resume is complete (after {@link #onResume} has
1317     * been called). Applications will generally not implement this method;
1318     * it is intended for system classes to do final setup after application
1319     * resume code has run.
1320     *
1321     * <p><em>Derived classes must call through to the super class's
1322     * implementation of this method.  If they do not, an exception will be
1323     * thrown.</em></p>
1324     *
1325     * @see #onResume
1326     */
1327    @CallSuper
1328    protected void onPostResume() {
1329        final Window win = getWindow();
1330        if (win != null) win.makeActive();
1331        if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(true);
1332        mCalled = true;
1333    }
1334
1335    void setVoiceInteractor(IVoiceInteractor voiceInteractor) {
1336        if (mVoiceInteractor != null) {
1337            for (Request activeRequest: mVoiceInteractor.getActiveRequests()) {
1338                activeRequest.cancel();
1339                activeRequest.clear();
1340            }
1341        }
1342        if (voiceInteractor == null) {
1343            mVoiceInteractor = null;
1344        } else {
1345            mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
1346                    Looper.myLooper());
1347        }
1348    }
1349
1350    /**
1351     * Gets the next accessibility ID.
1352     *
1353     * <p>All IDs will be bigger than {@link View#LAST_APP_ACCESSIBILITY_ID}. All IDs returned
1354     * will be unique.
1355     *
1356     * @return A ID that is unique in the activity
1357     *
1358     * {@hide}
1359     */
1360    @Override
1361    public int getNextAccessibilityId() {
1362        if (mLastAccessibilityId == Integer.MAX_VALUE - 1) {
1363            mLastAccessibilityId = View.LAST_APP_ACCESSIBILITY_ID;
1364        }
1365
1366        mLastAccessibilityId++;
1367
1368        return mLastAccessibilityId;
1369    }
1370
1371    /**
1372     * Check whether this activity is running as part of a voice interaction with the user.
1373     * If true, it should perform its interaction with the user through the
1374     * {@link VoiceInteractor} returned by {@link #getVoiceInteractor}.
1375     */
1376    public boolean isVoiceInteraction() {
1377        return mVoiceInteractor != null;
1378    }
1379
1380    /**
1381     * Like {@link #isVoiceInteraction}, but only returns true if this is also the root
1382     * of a voice interaction.  That is, returns true if this activity was directly
1383     * started by the voice interaction service as the initiation of a voice interaction.
1384     * Otherwise, for example if it was started by another activity while under voice
1385     * interaction, returns false.
1386     */
1387    public boolean isVoiceInteractionRoot() {
1388        try {
1389            return mVoiceInteractor != null
1390                    && ActivityManager.getService().isRootVoiceInteraction(mToken);
1391        } catch (RemoteException e) {
1392        }
1393        return false;
1394    }
1395
1396    /**
1397     * Retrieve the active {@link VoiceInteractor} that the user is going through to
1398     * interact with this activity.
1399     */
1400    public VoiceInteractor getVoiceInteractor() {
1401        return mVoiceInteractor;
1402    }
1403
1404    /**
1405     * Queries whether the currently enabled voice interaction service supports returning
1406     * a voice interactor for use by the activity. This is valid only for the duration of the
1407     * activity.
1408     *
1409     * @return whether the current voice interaction service supports local voice interaction
1410     */
1411    public boolean isLocalVoiceInteractionSupported() {
1412        try {
1413            return ActivityManager.getService().supportsLocalVoiceInteraction();
1414        } catch (RemoteException re) {
1415        }
1416        return false;
1417    }
1418
1419    /**
1420     * Starts a local voice interaction session. When ready,
1421     * {@link #onLocalVoiceInteractionStarted()} is called. You can pass a bundle of private options
1422     * to the registered voice interaction service.
1423     * @param privateOptions a Bundle of private arguments to the current voice interaction service
1424     */
1425    public void startLocalVoiceInteraction(Bundle privateOptions) {
1426        try {
1427            ActivityManager.getService().startLocalVoiceInteraction(mToken, privateOptions);
1428        } catch (RemoteException re) {
1429        }
1430    }
1431
1432    /**
1433     * Callback to indicate that {@link #startLocalVoiceInteraction(Bundle)} has resulted in a
1434     * voice interaction session being started. You can now retrieve a voice interactor using
1435     * {@link #getVoiceInteractor()}.
1436     */
1437    public void onLocalVoiceInteractionStarted() {
1438    }
1439
1440    /**
1441     * Callback to indicate that the local voice interaction has stopped either
1442     * because it was requested through a call to {@link #stopLocalVoiceInteraction()}
1443     * or because it was canceled by the user. The previously acquired {@link VoiceInteractor}
1444     * is no longer valid after this.
1445     */
1446    public void onLocalVoiceInteractionStopped() {
1447    }
1448
1449    /**
1450     * Request to terminate the current voice interaction that was previously started
1451     * using {@link #startLocalVoiceInteraction(Bundle)}. When the interaction is
1452     * terminated, {@link #onLocalVoiceInteractionStopped()} will be called.
1453     */
1454    public void stopLocalVoiceInteraction() {
1455        try {
1456            ActivityManager.getService().stopLocalVoiceInteraction(mToken);
1457        } catch (RemoteException re) {
1458        }
1459    }
1460
1461    /**
1462     * This is called for activities that set launchMode to "singleTop" in
1463     * their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP}
1464     * flag when calling {@link #startActivity}.  In either case, when the
1465     * activity is re-launched while at the top of the activity stack instead
1466     * of a new instance of the activity being started, onNewIntent() will be
1467     * called on the existing instance with the Intent that was used to
1468     * re-launch it.
1469     *
1470     * <p>An activity will always be paused before receiving a new intent, so
1471     * you can count on {@link #onResume} being called after this method.
1472     *
1473     * <p>Note that {@link #getIntent} still returns the original Intent.  You
1474     * can use {@link #setIntent} to update it to this new Intent.
1475     *
1476     * @param intent The new intent that was started for the activity.
1477     *
1478     * @see #getIntent
1479     * @see #setIntent
1480     * @see #onResume
1481     */
1482    protected void onNewIntent(Intent intent) {
1483    }
1484
1485    /**
1486     * The hook for {@link ActivityThread} to save the state of this activity.
1487     *
1488     * Calls {@link #onSaveInstanceState(android.os.Bundle)}
1489     * and {@link #saveManagedDialogs(android.os.Bundle)}.
1490     *
1491     * @param outState The bundle to save the state to.
1492     */
1493    final void performSaveInstanceState(Bundle outState) {
1494        onSaveInstanceState(outState);
1495        saveManagedDialogs(outState);
1496        mActivityTransitionState.saveState(outState);
1497        storeHasCurrentPermissionRequest(outState);
1498        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
1499    }
1500
1501    /**
1502     * The hook for {@link ActivityThread} to save the state of this activity.
1503     *
1504     * Calls {@link #onSaveInstanceState(android.os.Bundle)}
1505     * and {@link #saveManagedDialogs(android.os.Bundle)}.
1506     *
1507     * @param outState The bundle to save the state to.
1508     * @param outPersistentState The bundle to save persistent state to.
1509     */
1510    final void performSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
1511        onSaveInstanceState(outState, outPersistentState);
1512        saveManagedDialogs(outState);
1513        storeHasCurrentPermissionRequest(outState);
1514        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState +
1515                ", " + outPersistentState);
1516    }
1517
1518    /**
1519     * Called to retrieve per-instance state from an activity before being killed
1520     * so that the state can be restored in {@link #onCreate} or
1521     * {@link #onRestoreInstanceState} (the {@link Bundle} populated by this method
1522     * will be passed to both).
1523     *
1524     * <p>This method is called before an activity may be killed so that when it
1525     * comes back some time in the future it can restore its state.  For example,
1526     * if activity B is launched in front of activity A, and at some point activity
1527     * A is killed to reclaim resources, activity A will have a chance to save the
1528     * current state of its user interface via this method so that when the user
1529     * returns to activity A, the state of the user interface can be restored
1530     * via {@link #onCreate} or {@link #onRestoreInstanceState}.
1531     *
1532     * <p>Do not confuse this method with activity lifecycle callbacks such as
1533     * {@link #onPause}, which is always called when an activity is being placed
1534     * in the background or on its way to destruction, or {@link #onStop} which
1535     * is called before destruction.  One example of when {@link #onPause} and
1536     * {@link #onStop} is called and not this method is when a user navigates back
1537     * from activity B to activity A: there is no need to call {@link #onSaveInstanceState}
1538     * on B because that particular instance will never be restored, so the
1539     * system avoids calling it.  An example when {@link #onPause} is called and
1540     * not {@link #onSaveInstanceState} is when activity B is launched in front of activity A:
1541     * the system may avoid calling {@link #onSaveInstanceState} on activity A if it isn't
1542     * killed during the lifetime of B since the state of the user interface of
1543     * A will stay intact.
1544     *
1545     * <p>The default implementation takes care of most of the UI per-instance
1546     * state for you by calling {@link android.view.View#onSaveInstanceState()} on each
1547     * view in the hierarchy that has an id, and by saving the id of the currently
1548     * focused view (all of which is restored by the default implementation of
1549     * {@link #onRestoreInstanceState}).  If you override this method to save additional
1550     * information not captured by each individual view, you will likely want to
1551     * call through to the default implementation, otherwise be prepared to save
1552     * all of the state of each view yourself.
1553     *
1554     * <p>If called, this method will occur before {@link #onStop}.  There are
1555     * no guarantees about whether it will occur before or after {@link #onPause}.
1556     *
1557     * @param outState Bundle in which to place your saved state.
1558     *
1559     * @see #onCreate
1560     * @see #onRestoreInstanceState
1561     * @see #onPause
1562     */
1563    protected void onSaveInstanceState(Bundle outState) {
1564        outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
1565
1566        outState.putInt(LAST_ACCESSIBILITY_ID, mLastAccessibilityId);
1567        Parcelable p = mFragments.saveAllState();
1568        if (p != null) {
1569            outState.putParcelable(FRAGMENTS_TAG, p);
1570        }
1571        if (mAutoFillResetNeeded) {
1572            outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
1573            getAutofillManager().onSaveInstanceState(outState);
1574        }
1575        getApplication().dispatchActivitySaveInstanceState(this, outState);
1576    }
1577
1578    /**
1579     * This is the same as {@link #onSaveInstanceState} but is called for activities
1580     * created with the attribute {@link android.R.attr#persistableMode} set to
1581     * <code>persistAcrossReboots</code>. The {@link android.os.PersistableBundle} passed
1582     * in will be saved and presented in {@link #onCreate(Bundle, PersistableBundle)}
1583     * the first time that this activity is restarted following the next device reboot.
1584     *
1585     * @param outState Bundle in which to place your saved state.
1586     * @param outPersistentState State which will be saved across reboots.
1587     *
1588     * @see #onSaveInstanceState(Bundle)
1589     * @see #onCreate
1590     * @see #onRestoreInstanceState(Bundle, PersistableBundle)
1591     * @see #onPause
1592     */
1593    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
1594        onSaveInstanceState(outState);
1595    }
1596
1597    /**
1598     * Save the state of any managed dialogs.
1599     *
1600     * @param outState place to store the saved state.
1601     */
1602    private void saveManagedDialogs(Bundle outState) {
1603        if (mManagedDialogs == null) {
1604            return;
1605        }
1606
1607        final int numDialogs = mManagedDialogs.size();
1608        if (numDialogs == 0) {
1609            return;
1610        }
1611
1612        Bundle dialogState = new Bundle();
1613
1614        int[] ids = new int[mManagedDialogs.size()];
1615
1616        // save each dialog's bundle, gather the ids
1617        for (int i = 0; i < numDialogs; i++) {
1618            final int key = mManagedDialogs.keyAt(i);
1619            ids[i] = key;
1620            final ManagedDialog md = mManagedDialogs.valueAt(i);
1621            dialogState.putBundle(savedDialogKeyFor(key), md.mDialog.onSaveInstanceState());
1622            if (md.mArgs != null) {
1623                dialogState.putBundle(savedDialogArgsKeyFor(key), md.mArgs);
1624            }
1625        }
1626
1627        dialogState.putIntArray(SAVED_DIALOG_IDS_KEY, ids);
1628        outState.putBundle(SAVED_DIALOGS_TAG, dialogState);
1629    }
1630
1631
1632    /**
1633     * Called as part of the activity lifecycle when an activity is going into
1634     * the background, but has not (yet) been killed.  The counterpart to
1635     * {@link #onResume}.
1636     *
1637     * <p>When activity B is launched in front of activity A, this callback will
1638     * be invoked on A.  B will not be created until A's {@link #onPause} returns,
1639     * so be sure to not do anything lengthy here.
1640     *
1641     * <p>This callback is mostly used for saving any persistent state the
1642     * activity is editing, to present a "edit in place" model to the user and
1643     * making sure nothing is lost if there are not enough resources to start
1644     * the new activity without first killing this one.  This is also a good
1645     * place to do things like stop animations and other things that consume a
1646     * noticeable amount of CPU in order to make the switch to the next activity
1647     * as fast as possible, or to close resources that are exclusive access
1648     * such as the camera.
1649     *
1650     * <p>In situations where the system needs more memory it may kill paused
1651     * processes to reclaim resources.  Because of this, you should be sure
1652     * that all of your state is saved by the time you return from
1653     * this function.  In general {@link #onSaveInstanceState} is used to save
1654     * per-instance state in the activity and this method is used to store
1655     * global persistent data (in content providers, files, etc.)
1656     *
1657     * <p>After receiving this call you will usually receive a following call
1658     * to {@link #onStop} (after the next activity has been resumed and
1659     * displayed), however in some cases there will be a direct call back to
1660     * {@link #onResume} without going through the stopped state.
1661     *
1662     * <p><em>Derived classes must call through to the super class's
1663     * implementation of this method.  If they do not, an exception will be
1664     * thrown.</em></p>
1665     *
1666     * @see #onResume
1667     * @see #onSaveInstanceState
1668     * @see #onStop
1669     */
1670    @CallSuper
1671    protected void onPause() {
1672        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);
1673        getApplication().dispatchActivityPaused(this);
1674        mCalled = true;
1675    }
1676
1677    /**
1678     * Called as part of the activity lifecycle when an activity is about to go
1679     * into the background as the result of user choice.  For example, when the
1680     * user presses the Home key, {@link #onUserLeaveHint} will be called, but
1681     * when an incoming phone call causes the in-call Activity to be automatically
1682     * brought to the foreground, {@link #onUserLeaveHint} will not be called on
1683     * the activity being interrupted.  In cases when it is invoked, this method
1684     * is called right before the activity's {@link #onPause} callback.
1685     *
1686     * <p>This callback and {@link #onUserInteraction} are intended to help
1687     * activities manage status bar notifications intelligently; specifically,
1688     * for helping activities determine the proper time to cancel a notfication.
1689     *
1690     * @see #onUserInteraction()
1691     */
1692    protected void onUserLeaveHint() {
1693    }
1694
1695    /**
1696     * Generate a new thumbnail for this activity.  This method is called before
1697     * pausing the activity, and should draw into <var>outBitmap</var> the
1698     * imagery for the desired thumbnail in the dimensions of that bitmap.  It
1699     * can use the given <var>canvas</var>, which is configured to draw into the
1700     * bitmap, for rendering if desired.
1701     *
1702     * <p>The default implementation returns fails and does not draw a thumbnail;
1703     * this will result in the platform creating its own thumbnail if needed.
1704     *
1705     * @param outBitmap The bitmap to contain the thumbnail.
1706     * @param canvas Can be used to render into the bitmap.
1707     *
1708     * @return Return true if you have drawn into the bitmap; otherwise after
1709     *         you return it will be filled with a default thumbnail.
1710     *
1711     * @see #onCreateDescription
1712     * @see #onSaveInstanceState
1713     * @see #onPause
1714     */
1715    public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) {
1716        return false;
1717    }
1718
1719    /**
1720     * Generate a new description for this activity.  This method is called
1721     * before pausing the activity and can, if desired, return some textual
1722     * description of its current state to be displayed to the user.
1723     *
1724     * <p>The default implementation returns null, which will cause you to
1725     * inherit the description from the previous activity.  If all activities
1726     * return null, generally the label of the top activity will be used as the
1727     * description.
1728     *
1729     * @return A description of what the user is doing.  It should be short and
1730     *         sweet (only a few words).
1731     *
1732     * @see #onCreateThumbnail
1733     * @see #onSaveInstanceState
1734     * @see #onPause
1735     */
1736    @Nullable
1737    public CharSequence onCreateDescription() {
1738        return null;
1739    }
1740
1741    /**
1742     * This is called when the user is requesting an assist, to build a full
1743     * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
1744     * application.  You can override this method to place into the bundle anything
1745     * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
1746     * of the assist Intent.
1747     *
1748     * <p>This function will be called after any global assist callbacks that had
1749     * been registered with {@link Application#registerOnProvideAssistDataListener
1750     * Application.registerOnProvideAssistDataListener}.
1751     */
1752    public void onProvideAssistData(Bundle data) {
1753    }
1754
1755    /**
1756     * This is called when the user is requesting an assist, to provide references
1757     * to content related to the current activity.  Before being called, the
1758     * {@code outContent} Intent is filled with the base Intent of the activity (the Intent
1759     * returned by {@link #getIntent()}).  The Intent's extras are stripped of any types
1760     * that are not valid for {@link PersistableBundle} or non-framework Parcelables, and
1761     * the flags {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION} and
1762     * {@link Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION} are cleared from the Intent.
1763     *
1764     * <p>Custom implementation may adjust the content intent to better reflect the top-level
1765     * context of the activity, and fill in its ClipData with additional content of
1766     * interest that the user is currently viewing.  For example, an image gallery application
1767     * that has launched in to an activity allowing the user to swipe through pictures should
1768     * modify the intent to reference the current image they are looking it; such an
1769     * application when showing a list of pictures should add a ClipData that has
1770     * references to all of the pictures currently visible on screen.</p>
1771     *
1772     * @param outContent The assist content to return.
1773     */
1774    public void onProvideAssistContent(AssistContent outContent) {
1775    }
1776
1777    /**
1778     * Request the Keyboard Shortcuts screen to show up. This will trigger
1779     * {@link #onProvideKeyboardShortcuts} to retrieve the shortcuts for the foreground activity.
1780     */
1781    public final void requestShowKeyboardShortcuts() {
1782        Intent intent = new Intent(Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS);
1783        intent.setPackage(KEYBOARD_SHORTCUTS_RECEIVER_PKG_NAME);
1784        sendBroadcastAsUser(intent, UserHandle.SYSTEM);
1785    }
1786
1787    /**
1788     * Dismiss the Keyboard Shortcuts screen.
1789     */
1790    public final void dismissKeyboardShortcutsHelper() {
1791        Intent intent = new Intent(Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS);
1792        intent.setPackage(KEYBOARD_SHORTCUTS_RECEIVER_PKG_NAME);
1793        sendBroadcastAsUser(intent, UserHandle.SYSTEM);
1794    }
1795
1796    @Override
1797    public void onProvideKeyboardShortcuts(
1798            List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {
1799        if (menu == null) {
1800          return;
1801        }
1802        KeyboardShortcutGroup group = null;
1803        int menuSize = menu.size();
1804        for (int i = 0; i < menuSize; ++i) {
1805            final MenuItem item = menu.getItem(i);
1806            final CharSequence title = item.getTitle();
1807            final char alphaShortcut = item.getAlphabeticShortcut();
1808            final int alphaModifiers = item.getAlphabeticModifiers();
1809            if (title != null && alphaShortcut != MIN_VALUE) {
1810                if (group == null) {
1811                    final int resource = mApplication.getApplicationInfo().labelRes;
1812                    group = new KeyboardShortcutGroup(resource != 0 ? getString(resource) : null);
1813                }
1814                group.addItem(new KeyboardShortcutInfo(
1815                    title, alphaShortcut, alphaModifiers));
1816            }
1817        }
1818        if (group != null) {
1819            data.add(group);
1820        }
1821    }
1822
1823    /**
1824     * Ask to have the current assistant shown to the user.  This only works if the calling
1825     * activity is the current foreground activity.  It is the same as calling
1826     * {@link android.service.voice.VoiceInteractionService#showSession
1827     * VoiceInteractionService.showSession} and requesting all of the possible context.
1828     * The receiver will always see
1829     * {@link android.service.voice.VoiceInteractionSession#SHOW_SOURCE_APPLICATION} set.
1830     * @return Returns true if the assistant was successfully invoked, else false.  For example
1831     * false will be returned if the caller is not the current top activity.
1832     */
1833    public boolean showAssist(Bundle args) {
1834        try {
1835            return ActivityManager.getService().showAssistFromActivity(mToken, args);
1836        } catch (RemoteException e) {
1837        }
1838        return false;
1839    }
1840
1841    /**
1842     * Called when you are no longer visible to the user.  You will next
1843     * receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
1844     * depending on later user activity.
1845     *
1846     * <p><em>Derived classes must call through to the super class's
1847     * implementation of this method.  If they do not, an exception will be
1848     * thrown.</em></p>
1849     *
1850     * @see #onRestart
1851     * @see #onResume
1852     * @see #onSaveInstanceState
1853     * @see #onDestroy
1854     */
1855    @CallSuper
1856    protected void onStop() {
1857        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this);
1858        if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
1859        mActivityTransitionState.onStop();
1860        getApplication().dispatchActivityStopped(this);
1861        mTranslucentCallback = null;
1862        mCalled = true;
1863        if (isFinishing() && mAutoFillResetNeeded) {
1864            getAutofillManager().commit();
1865        }
1866    }
1867
1868    /**
1869     * Perform any final cleanup before an activity is destroyed.  This can
1870     * happen either because the activity is finishing (someone called
1871     * {@link #finish} on it, or because the system is temporarily destroying
1872     * this instance of the activity to save space.  You can distinguish
1873     * between these two scenarios with the {@link #isFinishing} method.
1874     *
1875     * <p><em>Note: do not count on this method being called as a place for
1876     * saving data! For example, if an activity is editing data in a content
1877     * provider, those edits should be committed in either {@link #onPause} or
1878     * {@link #onSaveInstanceState}, not here.</em> This method is usually implemented to
1879     * free resources like threads that are associated with an activity, so
1880     * that a destroyed activity does not leave such things around while the
1881     * rest of its application is still running.  There are situations where
1882     * the system will simply kill the activity's hosting process without
1883     * calling this method (or any others) in it, so it should not be used to
1884     * do things that are intended to remain around after the process goes
1885     * away.
1886     *
1887     * <p><em>Derived classes must call through to the super class's
1888     * implementation of this method.  If they do not, an exception will be
1889     * thrown.</em></p>
1890     *
1891     * @see #onPause
1892     * @see #onStop
1893     * @see #finish
1894     * @see #isFinishing
1895     */
1896    @CallSuper
1897    protected void onDestroy() {
1898        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
1899        mCalled = true;
1900
1901        // dismiss any dialogs we are managing.
1902        if (mManagedDialogs != null) {
1903            final int numDialogs = mManagedDialogs.size();
1904            for (int i = 0; i < numDialogs; i++) {
1905                final ManagedDialog md = mManagedDialogs.valueAt(i);
1906                if (md.mDialog.isShowing()) {
1907                    md.mDialog.dismiss();
1908                }
1909            }
1910            mManagedDialogs = null;
1911        }
1912
1913        // close any cursors we are managing.
1914        synchronized (mManagedCursors) {
1915            int numCursors = mManagedCursors.size();
1916            for (int i = 0; i < numCursors; i++) {
1917                ManagedCursor c = mManagedCursors.get(i);
1918                if (c != null) {
1919                    c.mCursor.close();
1920                }
1921            }
1922            mManagedCursors.clear();
1923        }
1924
1925        // Close any open search dialog
1926        if (mSearchManager != null) {
1927            mSearchManager.stopSearch();
1928        }
1929
1930        if (mActionBar != null) {
1931            mActionBar.onDestroy();
1932        }
1933
1934        getApplication().dispatchActivityDestroyed(this);
1935    }
1936
1937    /**
1938     * Report to the system that your app is now fully drawn, purely for diagnostic
1939     * purposes (calling it does not impact the visible behavior of the activity).
1940     * This is only used to help instrument application launch times, so that the
1941     * app can report when it is fully in a usable state; without this, the only thing
1942     * the system itself can determine is the point at which the activity's window
1943     * is <em>first</em> drawn and displayed.  To participate in app launch time
1944     * measurement, you should always call this method after first launch (when
1945     * {@link #onCreate(android.os.Bundle)} is called), at the point where you have
1946     * entirely drawn your UI and populated with all of the significant data.  You
1947     * can safely call this method any time after first launch as well, in which case
1948     * it will simply be ignored.
1949     */
1950    public void reportFullyDrawn() {
1951        if (mDoReportFullyDrawn) {
1952            mDoReportFullyDrawn = false;
1953            try {
1954                ActivityManager.getService().reportActivityFullyDrawn(mToken);
1955            } catch (RemoteException e) {
1956            }
1957        }
1958    }
1959
1960    /**
1961     * Called by the system when the activity changes from fullscreen mode to multi-window mode and
1962     * visa-versa. This method provides the same configuration that will be sent in the following
1963     * {@link #onConfigurationChanged(Configuration)} call after the activity enters this mode.
1964     *
1965     * @see android.R.attr#resizeableActivity
1966     *
1967     * @param isInMultiWindowMode True if the activity is in multi-window mode.
1968     * @param newConfig The new configuration of the activity with the state
1969     *                  {@param isInMultiWindowMode}.
1970     */
1971    public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
1972        // Left deliberately empty. There should be no side effects if a direct
1973        // subclass of Activity does not call super.
1974        onMultiWindowModeChanged(isInMultiWindowMode);
1975    }
1976
1977    /**
1978     * Called by the system when the activity changes from fullscreen mode to multi-window mode and
1979     * visa-versa.
1980     *
1981     * @see android.R.attr#resizeableActivity
1982     *
1983     * @param isInMultiWindowMode True if the activity is in multi-window mode.
1984     *
1985     * @deprecated Use {@link #onMultiWindowModeChanged(boolean, Configuration)} instead.
1986     */
1987    @Deprecated
1988    public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
1989        // Left deliberately empty. There should be no side effects if a direct
1990        // subclass of Activity does not call super.
1991    }
1992
1993    /**
1994     * Returns true if the activity is currently in multi-window mode.
1995     * @see android.R.attr#resizeableActivity
1996     *
1997     * @return True if the activity is in multi-window mode.
1998     */
1999    public boolean isInMultiWindowMode() {
2000        try {
2001            return ActivityManager.getService().isInMultiWindowMode(mToken);
2002        } catch (RemoteException e) {
2003        }
2004        return false;
2005    }
2006
2007    /**
2008     * Called by the system when the activity changes to and from picture-in-picture mode. This
2009     * method provides the same configuration that will be sent in the following
2010     * {@link #onConfigurationChanged(Configuration)} call after the activity enters this mode.
2011     *
2012     * @see android.R.attr#supportsPictureInPicture
2013     *
2014     * @param isInPictureInPictureMode True if the activity is in picture-in-picture mode.
2015     * @param newConfig The new configuration of the activity with the state
2016     *                  {@param isInPictureInPictureMode}.
2017     */
2018    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode,
2019            Configuration newConfig) {
2020        // Left deliberately empty. There should be no side effects if a direct
2021        // subclass of Activity does not call super.
2022        onPictureInPictureModeChanged(isInPictureInPictureMode);
2023    }
2024
2025    /**
2026     * Called by the system when the activity changes to and from picture-in-picture mode.
2027     *
2028     * @see android.R.attr#supportsPictureInPicture
2029     *
2030     * @param isInPictureInPictureMode True if the activity is in picture-in-picture mode.
2031     *
2032     * @deprecated Use {@link #onPictureInPictureModeChanged(boolean, Configuration)} instead.
2033     */
2034    @Deprecated
2035    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
2036        // Left deliberately empty. There should be no side effects if a direct
2037        // subclass of Activity does not call super.
2038    }
2039
2040    /**
2041     * Returns true if the activity is currently in picture-in-picture mode.
2042     * @see android.R.attr#supportsPictureInPicture
2043     *
2044     * @return True if the activity is in picture-in-picture mode.
2045     */
2046    public boolean isInPictureInPictureMode() {
2047        try {
2048            return ActivityManager.getService().isInPictureInPictureMode(mToken);
2049        } catch (RemoteException e) {
2050        }
2051        return false;
2052    }
2053
2054    /**
2055     * Puts the activity in picture-in-picture mode if possible in the current system state. Any
2056     * prior calls to {@link #setPictureInPictureParams(PictureInPictureParams)} will still apply
2057     * when entering picture-in-picture through this call.
2058     *
2059     * @see #enterPictureInPictureMode(PictureInPictureParams)
2060     * @see android.R.attr#supportsPictureInPicture
2061     */
2062    @Deprecated
2063    public void enterPictureInPictureMode() {
2064        enterPictureInPictureMode(new PictureInPictureParams.Builder().build());
2065    }
2066
2067    /** @removed */
2068    @Deprecated
2069    public boolean enterPictureInPictureMode(@NonNull PictureInPictureArgs args) {
2070        return enterPictureInPictureMode(PictureInPictureArgs.convert(args));
2071    }
2072
2073    /**
2074     * Puts the activity in picture-in-picture mode if possible in the current system state. The
2075     * set parameters in {@param params} will be combined with the parameters from prior calls to
2076     * {@link #setPictureInPictureParams(PictureInPictureParams)}.
2077     *
2078     * The system may disallow entering picture-in-picture in various cases, including when the
2079     * activity is not visible, if the screen is locked or if the user has an activity pinned.
2080     *
2081     * @see android.R.attr#supportsPictureInPicture
2082     * @see PictureInPictureParams
2083     *
2084     * @param params non-null parameters to be combined with previously set parameters when entering
2085     * picture-in-picture.
2086     *
2087     * @return true if the system puts this activity into picture-in-picture mode or was already
2088     * in picture-in-picture mode (@see {@link #isInPictureInPictureMode())
2089     */
2090    public boolean enterPictureInPictureMode(@NonNull PictureInPictureParams params) {
2091        try {
2092            if (params == null) {
2093                throw new IllegalArgumentException("Expected non-null picture-in-picture params");
2094            }
2095            updatePictureInPictureParamsForContentInsets(params);
2096            return ActivityManagerNative.getDefault().enterPictureInPictureMode(mToken, params);
2097        } catch (RemoteException e) {
2098            return false;
2099        }
2100    }
2101
2102    /** @removed */
2103    @Deprecated
2104    public void setPictureInPictureArgs(@NonNull PictureInPictureArgs args) {
2105        setPictureInPictureParams(PictureInPictureArgs.convert(args));
2106    }
2107
2108    /**
2109     * Updates the properties of the picture-in-picture activity, or sets it to be used later when
2110     * {@link #enterPictureInPictureMode()} is called.
2111     *
2112     * @param params the new parameters for the picture-in-picture.
2113     */
2114    public void setPictureInPictureParams(@NonNull PictureInPictureParams params) {
2115        try {
2116            if (params == null) {
2117                throw new IllegalArgumentException("Expected non-null picture-in-picture params");
2118            }
2119            updatePictureInPictureParamsForContentInsets(params);
2120            ActivityManagerNative.getDefault().setPictureInPictureParams(mToken, params);
2121        } catch (RemoteException e) {
2122        }
2123    }
2124
2125    /**
2126     * Return the number of actions that will be displayed in the picture-in-picture UI when the
2127     * user interacts with the activity currently in picture-in-picture mode. This number may change
2128     * if the global configuration changes (ie. if the device is plugged into an external display),
2129     * but will always be larger than three.
2130     */
2131    public int getMaxNumPictureInPictureActions() {
2132        try {
2133            return ActivityManagerNative.getDefault().getMaxNumPictureInPictureActions(mToken);
2134        } catch (RemoteException e) {
2135            return 0;
2136        }
2137    }
2138
2139    /**
2140     * Updates the provided {@param params} with the last known content insets for this activity, to
2141     * be used with the source hint rect for the transition into PiP.
2142     */
2143    private void updatePictureInPictureParamsForContentInsets(PictureInPictureParams params) {
2144        if (params != null && params.hasSourceBoundsHint() && getWindow() != null &&
2145                getWindow().peekDecorView() != null &&
2146                getWindow().peekDecorView().getViewRootImpl() != null) {
2147            params.setSourceRectHintInsets(
2148                    getWindow().peekDecorView().getViewRootImpl().getLastContentInsets());
2149        } else {
2150            params.setSourceRectHintInsets(null);
2151        }
2152    }
2153
2154    void dispatchMovedToDisplay(int displayId, Configuration config) {
2155        updateDisplay(displayId);
2156        onMovedToDisplay(displayId, config);
2157    }
2158
2159    /**
2160     * Called by the system when the activity is moved from one display to another without
2161     * recreation. This means that this activity is declared to handle all changes to configuration
2162     * that happened when it was switched to another display, so it wasn't destroyed and created
2163     * again.
2164     *
2165     * <p>This call will be followed by {@link #onConfigurationChanged(Configuration)} if the
2166     * applied configuration actually changed. It is up to app developer to choose whether to handle
2167     * the change in this method or in the following {@link #onConfigurationChanged(Configuration)}
2168     * call.
2169     *
2170     * <p>Use this callback to track changes to the displays if some activity functionality relies
2171     * on an association with some display properties.
2172     *
2173     * @param displayId The id of the display to which activity was moved.
2174     * @param config Configuration of the activity resources on new display after move.
2175     *
2176     * @see #onConfigurationChanged(Configuration)
2177     * @see View#onMovedToDisplay(int, Configuration)
2178     * @hide
2179     */
2180    public void onMovedToDisplay(int displayId, Configuration config) {
2181    }
2182
2183    /**
2184     * Called by the system when the device configuration changes while your
2185     * activity is running.  Note that this will <em>only</em> be called if
2186     * you have selected configurations you would like to handle with the
2187     * {@link android.R.attr#configChanges} attribute in your manifest.  If
2188     * any configuration change occurs that is not selected to be reported
2189     * by that attribute, then instead of reporting it the system will stop
2190     * and restart the activity (to have it launched with the new
2191     * configuration).
2192     *
2193     * <p>At the time that this function has been called, your Resources
2194     * object will have been updated to return resource values matching the
2195     * new configuration.
2196     *
2197     * @param newConfig The new device configuration.
2198     */
2199    public void onConfigurationChanged(Configuration newConfig) {
2200        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onConfigurationChanged " + this + ": " + newConfig);
2201        mCalled = true;
2202
2203        mFragments.dispatchConfigurationChanged(newConfig);
2204
2205        if (mWindow != null) {
2206            // Pass the configuration changed event to the window
2207            mWindow.onConfigurationChanged(newConfig);
2208        }
2209
2210        if (mActionBar != null) {
2211            // Do this last; the action bar will need to access
2212            // view changes from above.
2213            mActionBar.onConfigurationChanged(newConfig);
2214        }
2215    }
2216
2217    /**
2218     * If this activity is being destroyed because it can not handle a
2219     * configuration parameter being changed (and thus its
2220     * {@link #onConfigurationChanged(Configuration)} method is
2221     * <em>not</em> being called), then you can use this method to discover
2222     * the set of changes that have occurred while in the process of being
2223     * destroyed.  Note that there is no guarantee that these will be
2224     * accurate (other changes could have happened at any time), so you should
2225     * only use this as an optimization hint.
2226     *
2227     * @return Returns a bit field of the configuration parameters that are
2228     * changing, as defined by the {@link android.content.res.Configuration}
2229     * class.
2230     */
2231    public int getChangingConfigurations() {
2232        return mConfigChangeFlags;
2233    }
2234
2235    /**
2236     * Retrieve the non-configuration instance data that was previously
2237     * returned by {@link #onRetainNonConfigurationInstance()}.  This will
2238     * be available from the initial {@link #onCreate} and
2239     * {@link #onStart} calls to the new instance, allowing you to extract
2240     * any useful dynamic state from the previous instance.
2241     *
2242     * <p>Note that the data you retrieve here should <em>only</em> be used
2243     * as an optimization for handling configuration changes.  You should always
2244     * be able to handle getting a null pointer back, and an activity must
2245     * still be able to restore itself to its previous state (through the
2246     * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this
2247     * function returns null.
2248     *
2249     * <p><strong>Note:</strong> For most cases you should use the {@link Fragment} API
2250     * {@link Fragment#setRetainInstance(boolean)} instead; this is also
2251     * available on older platforms through the Android support libraries.
2252     *
2253     * @return the object previously returned by {@link #onRetainNonConfigurationInstance()}
2254     */
2255    @Nullable
2256    public Object getLastNonConfigurationInstance() {
2257        return mLastNonConfigurationInstances != null
2258                ? mLastNonConfigurationInstances.activity : null;
2259    }
2260
2261    /**
2262     * Called by the system, as part of destroying an
2263     * activity due to a configuration change, when it is known that a new
2264     * instance will immediately be created for the new configuration.  You
2265     * can return any object you like here, including the activity instance
2266     * itself, which can later be retrieved by calling
2267     * {@link #getLastNonConfigurationInstance()} in the new activity
2268     * instance.
2269     *
2270     * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
2271     * or later, consider instead using a {@link Fragment} with
2272     * {@link Fragment#setRetainInstance(boolean)
2273     * Fragment.setRetainInstance(boolean}.</em>
2274     *
2275     * <p>This function is called purely as an optimization, and you must
2276     * not rely on it being called.  When it is called, a number of guarantees
2277     * will be made to help optimize configuration switching:
2278     * <ul>
2279     * <li> The function will be called between {@link #onStop} and
2280     * {@link #onDestroy}.
2281     * <li> A new instance of the activity will <em>always</em> be immediately
2282     * created after this one's {@link #onDestroy()} is called.  In particular,
2283     * <em>no</em> messages will be dispatched during this time (when the returned
2284     * object does not have an activity to be associated with).
2285     * <li> The object you return here will <em>always</em> be available from
2286     * the {@link #getLastNonConfigurationInstance()} method of the following
2287     * activity instance as described there.
2288     * </ul>
2289     *
2290     * <p>These guarantees are designed so that an activity can use this API
2291     * to propagate extensive state from the old to new activity instance, from
2292     * loaded bitmaps, to network connections, to evenly actively running
2293     * threads.  Note that you should <em>not</em> propagate any data that
2294     * may change based on the configuration, including any data loaded from
2295     * resources such as strings, layouts, or drawables.
2296     *
2297     * <p>The guarantee of no message handling during the switch to the next
2298     * activity simplifies use with active objects.  For example if your retained
2299     * state is an {@link android.os.AsyncTask} you are guaranteed that its
2300     * call back functions (like {@link android.os.AsyncTask#onPostExecute}) will
2301     * not be called from the call here until you execute the next instance's
2302     * {@link #onCreate(Bundle)}.  (Note however that there is of course no such
2303     * guarantee for {@link android.os.AsyncTask#doInBackground} since that is
2304     * running in a separate thread.)
2305     *
2306     * <p><strong>Note:</strong> For most cases you should use the {@link Fragment} API
2307     * {@link Fragment#setRetainInstance(boolean)} instead; this is also
2308     * available on older platforms through the Android support libraries.
2309     *
2310     * @return any Object holding the desired state to propagate to the
2311     *         next activity instance
2312     */
2313    public Object onRetainNonConfigurationInstance() {
2314        return null;
2315    }
2316
2317    /**
2318     * Retrieve the non-configuration instance data that was previously
2319     * returned by {@link #onRetainNonConfigurationChildInstances()}.  This will
2320     * be available from the initial {@link #onCreate} and
2321     * {@link #onStart} calls to the new instance, allowing you to extract
2322     * any useful dynamic state from the previous instance.
2323     *
2324     * <p>Note that the data you retrieve here should <em>only</em> be used
2325     * as an optimization for handling configuration changes.  You should always
2326     * be able to handle getting a null pointer back, and an activity must
2327     * still be able to restore itself to its previous state (through the
2328     * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this
2329     * function returns null.
2330     *
2331     * @return Returns the object previously returned by
2332     * {@link #onRetainNonConfigurationChildInstances()}
2333     */
2334    @Nullable
2335    HashMap<String, Object> getLastNonConfigurationChildInstances() {
2336        return mLastNonConfigurationInstances != null
2337                ? mLastNonConfigurationInstances.children : null;
2338    }
2339
2340    /**
2341     * This method is similar to {@link #onRetainNonConfigurationInstance()} except that
2342     * it should return either a mapping from  child activity id strings to arbitrary objects,
2343     * or null.  This method is intended to be used by Activity framework subclasses that control a
2344     * set of child activities, such as ActivityGroup.  The same guarantees and restrictions apply
2345     * as for {@link #onRetainNonConfigurationInstance()}.  The default implementation returns null.
2346     */
2347    @Nullable
2348    HashMap<String,Object> onRetainNonConfigurationChildInstances() {
2349        return null;
2350    }
2351
2352    NonConfigurationInstances retainNonConfigurationInstances() {
2353        Object activity = onRetainNonConfigurationInstance();
2354        HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
2355        FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();
2356
2357        // We're already stopped but we've been asked to retain.
2358        // Our fragments are taken care of but we need to mark the loaders for retention.
2359        // In order to do this correctly we need to restart the loaders first before
2360        // handing them off to the next activity.
2361        mFragments.doLoaderStart();
2362        mFragments.doLoaderStop(true);
2363        ArrayMap<String, LoaderManager> loaders = mFragments.retainLoaderNonConfig();
2364
2365        if (activity == null && children == null && fragments == null && loaders == null
2366                && mVoiceInteractor == null) {
2367            return null;
2368        }
2369
2370        NonConfigurationInstances nci = new NonConfigurationInstances();
2371        nci.activity = activity;
2372        nci.children = children;
2373        nci.fragments = fragments;
2374        nci.loaders = loaders;
2375        if (mVoiceInteractor != null) {
2376            mVoiceInteractor.retainInstance();
2377            nci.voiceInteractor = mVoiceInteractor;
2378        }
2379        return nci;
2380    }
2381
2382    public void onLowMemory() {
2383        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onLowMemory " + this);
2384        mCalled = true;
2385        mFragments.dispatchLowMemory();
2386    }
2387
2388    public void onTrimMemory(int level) {
2389        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onTrimMemory " + this + ": " + level);
2390        mCalled = true;
2391        mFragments.dispatchTrimMemory(level);
2392    }
2393
2394    /**
2395     * Return the FragmentManager for interacting with fragments associated
2396     * with this activity.
2397     */
2398    public FragmentManager getFragmentManager() {
2399        return mFragments.getFragmentManager();
2400    }
2401
2402    /**
2403     * Called when a Fragment is being attached to this activity, immediately
2404     * after the call to its {@link Fragment#onAttach Fragment.onAttach()}
2405     * method and before {@link Fragment#onCreate Fragment.onCreate()}.
2406     */
2407    public void onAttachFragment(Fragment fragment) {
2408    }
2409
2410    /**
2411     * Wrapper around
2412     * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)}
2413     * that gives the resulting {@link Cursor} to call
2414     * {@link #startManagingCursor} so that the activity will manage its
2415     * lifecycle for you.
2416     *
2417     * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
2418     * or later, consider instead using {@link LoaderManager} instead, available
2419     * via {@link #getLoaderManager()}.</em>
2420     *
2421     * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on a cursor obtained using
2422     * this method, because the activity will do that for you at the appropriate time. However, if
2423     * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will
2424     * not</em> automatically close the cursor and, in that case, you must call
2425     * {@link Cursor#close()}.</p>
2426     *
2427     * @param uri The URI of the content provider to query.
2428     * @param projection List of columns to return.
2429     * @param selection SQL WHERE clause.
2430     * @param sortOrder SQL ORDER BY clause.
2431     *
2432     * @return The Cursor that was returned by query().
2433     *
2434     * @see ContentResolver#query(android.net.Uri , String[], String, String[], String)
2435     * @see #startManagingCursor
2436     * @hide
2437     *
2438     * @deprecated Use {@link CursorLoader} instead.
2439     */
2440    @Deprecated
2441    public final Cursor managedQuery(Uri uri, String[] projection, String selection,
2442            String sortOrder) {
2443        Cursor c = getContentResolver().query(uri, projection, selection, null, sortOrder);
2444        if (c != null) {
2445            startManagingCursor(c);
2446        }
2447        return c;
2448    }
2449
2450    /**
2451     * Wrapper around
2452     * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)}
2453     * that gives the resulting {@link Cursor} to call
2454     * {@link #startManagingCursor} so that the activity will manage its
2455     * lifecycle for you.
2456     *
2457     * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
2458     * or later, consider instead using {@link LoaderManager} instead, available
2459     * via {@link #getLoaderManager()}.</em>
2460     *
2461     * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on a cursor obtained using
2462     * this method, because the activity will do that for you at the appropriate time. However, if
2463     * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will
2464     * not</em> automatically close the cursor and, in that case, you must call
2465     * {@link Cursor#close()}.</p>
2466     *
2467     * @param uri The URI of the content provider to query.
2468     * @param projection List of columns to return.
2469     * @param selection SQL WHERE clause.
2470     * @param selectionArgs The arguments to selection, if any ?s are pesent
2471     * @param sortOrder SQL ORDER BY clause.
2472     *
2473     * @return The Cursor that was returned by query().
2474     *
2475     * @see ContentResolver#query(android.net.Uri , String[], String, String[], String)
2476     * @see #startManagingCursor
2477     *
2478     * @deprecated Use {@link CursorLoader} instead.
2479     */
2480    @Deprecated
2481    public final Cursor managedQuery(Uri uri, String[] projection, String selection,
2482            String[] selectionArgs, String sortOrder) {
2483        Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
2484        if (c != null) {
2485            startManagingCursor(c);
2486        }
2487        return c;
2488    }
2489
2490    /**
2491     * This method allows the activity to take care of managing the given
2492     * {@link Cursor}'s lifecycle for you based on the activity's lifecycle.
2493     * That is, when the activity is stopped it will automatically call
2494     * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted
2495     * it will call {@link Cursor#requery} for you.  When the activity is
2496     * destroyed, all managed Cursors will be closed automatically.
2497     *
2498     * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
2499     * or later, consider instead using {@link LoaderManager} instead, available
2500     * via {@link #getLoaderManager()}.</em>
2501     *
2502     * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on cursor obtained from
2503     * {@link #managedQuery}, because the activity will do that for you at the appropriate time.
2504     * However, if you call {@link #stopManagingCursor} on a cursor from a managed query, the system
2505     * <em>will not</em> automatically close the cursor and, in that case, you must call
2506     * {@link Cursor#close()}.</p>
2507     *
2508     * @param c The Cursor to be managed.
2509     *
2510     * @see #managedQuery(android.net.Uri , String[], String, String[], String)
2511     * @see #stopManagingCursor
2512     *
2513     * @deprecated Use the new {@link android.content.CursorLoader} class with
2514     * {@link LoaderManager} instead; this is also
2515     * available on older platforms through the Android compatibility package.
2516     */
2517    @Deprecated
2518    public void startManagingCursor(Cursor c) {
2519        synchronized (mManagedCursors) {
2520            mManagedCursors.add(new ManagedCursor(c));
2521        }
2522    }
2523
2524    /**
2525     * Given a Cursor that was previously given to
2526     * {@link #startManagingCursor}, stop the activity's management of that
2527     * cursor.
2528     *
2529     * <p><strong>Warning:</strong> After calling this method on a cursor from a managed query,
2530     * the system <em>will not</em> automatically close the cursor and you must call
2531     * {@link Cursor#close()}.</p>
2532     *
2533     * @param c The Cursor that was being managed.
2534     *
2535     * @see #startManagingCursor
2536     *
2537     * @deprecated Use the new {@link android.content.CursorLoader} class with
2538     * {@link LoaderManager} instead; this is also
2539     * available on older platforms through the Android compatibility package.
2540     */
2541    @Deprecated
2542    public void stopManagingCursor(Cursor c) {
2543        synchronized (mManagedCursors) {
2544            final int N = mManagedCursors.size();
2545            for (int i=0; i<N; i++) {
2546                ManagedCursor mc = mManagedCursors.get(i);
2547                if (mc.mCursor == c) {
2548                    mManagedCursors.remove(i);
2549                    break;
2550                }
2551            }
2552        }
2553    }
2554
2555    /**
2556     * @deprecated As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}
2557     * this is a no-op.
2558     * @hide
2559     */
2560    @Deprecated
2561    public void setPersistent(boolean isPersistent) {
2562    }
2563
2564    /**
2565     * Finds a view that was identified by the {@code android:id} XML attribute
2566     * that was processed in {@link #onCreate}.
2567     * <p>
2568     * <strong>Note:</strong> In most cases -- depending on compiler support --
2569     * the resulting view is automatically cast to the target class type. If
2570     * the target class type is unconstrained, an explicit cast may be
2571     * necessary.
2572     *
2573     * @param id the ID to search for
2574     * @return a view with given ID if found, or {@code null} otherwise
2575     * @see View#findViewById(int)
2576     */
2577    @Nullable
2578    public <T extends View> T findViewById(@IdRes int id) {
2579        return getWindow().findViewById(id);
2580    }
2581
2582    /**
2583     * Retrieve a reference to this activity's ActionBar.
2584     *
2585     * @return The Activity's ActionBar, or null if it does not have one.
2586     */
2587    @Nullable
2588    public ActionBar getActionBar() {
2589        initWindowDecorActionBar();
2590        return mActionBar;
2591    }
2592
2593    /**
2594     * Set a {@link android.widget.Toolbar Toolbar} to act as the {@link ActionBar} for this
2595     * Activity window.
2596     *
2597     * <p>When set to a non-null value the {@link #getActionBar()} method will return
2598     * an {@link ActionBar} object that can be used to control the given toolbar as if it were
2599     * a traditional window decor action bar. The toolbar's menu will be populated with the
2600     * Activity's options menu and the navigation button will be wired through the standard
2601     * {@link android.R.id#home home} menu select action.</p>
2602     *
2603     * <p>In order to use a Toolbar within the Activity's window content the application
2604     * must not request the window feature {@link Window#FEATURE_ACTION_BAR FEATURE_ACTION_BAR}.</p>
2605     *
2606     * @param toolbar Toolbar to set as the Activity's action bar, or {@code null} to clear it
2607     */
2608    public void setActionBar(@Nullable Toolbar toolbar) {
2609        final ActionBar ab = getActionBar();
2610        if (ab instanceof WindowDecorActionBar) {
2611            throw new IllegalStateException("This Activity already has an action bar supplied " +
2612                    "by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " +
2613                    "android:windowActionBar to false in your theme to use a Toolbar instead.");
2614        }
2615
2616        // If we reach here then we're setting a new action bar
2617        // First clear out the MenuInflater to make sure that it is valid for the new Action Bar
2618        mMenuInflater = null;
2619
2620        // If we have an action bar currently, destroy it
2621        if (ab != null) {
2622            ab.onDestroy();
2623        }
2624
2625        if (toolbar != null) {
2626            final ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this);
2627            mActionBar = tbab;
2628            mWindow.setCallback(tbab.getWrappedWindowCallback());
2629        } else {
2630            mActionBar = null;
2631            // Re-set the original window callback since we may have already set a Toolbar wrapper
2632            mWindow.setCallback(this);
2633        }
2634
2635        invalidateOptionsMenu();
2636    }
2637
2638    /**
2639     * Creates a new ActionBar, locates the inflated ActionBarView,
2640     * initializes the ActionBar with the view, and sets mActionBar.
2641     */
2642    private void initWindowDecorActionBar() {
2643        Window window = getWindow();
2644
2645        // Initializing the window decor can change window feature flags.
2646        // Make sure that we have the correct set before performing the test below.
2647        window.getDecorView();
2648
2649        if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) {
2650            return;
2651        }
2652
2653        mActionBar = new WindowDecorActionBar(this);
2654        mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
2655
2656        mWindow.setDefaultIcon(mActivityInfo.getIconResource());
2657        mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
2658    }
2659
2660    /**
2661     * Set the activity content from a layout resource.  The resource will be
2662     * inflated, adding all top-level views to the activity.
2663     *
2664     * @param layoutResID Resource ID to be inflated.
2665     *
2666     * @see #setContentView(android.view.View)
2667     * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
2668     */
2669    public void setContentView(@LayoutRes int layoutResID) {
2670        getWindow().setContentView(layoutResID);
2671        initWindowDecorActionBar();
2672    }
2673
2674    /**
2675     * Set the activity content to an explicit view.  This view is placed
2676     * directly into the activity's view hierarchy.  It can itself be a complex
2677     * view hierarchy.  When calling this method, the layout parameters of the
2678     * specified view are ignored.  Both the width and the height of the view are
2679     * set by default to {@link ViewGroup.LayoutParams#MATCH_PARENT}. To use
2680     * your own layout parameters, invoke
2681     * {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}
2682     * instead.
2683     *
2684     * @param view The desired content to display.
2685     *
2686     * @see #setContentView(int)
2687     * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
2688     */
2689    public void setContentView(View view) {
2690        getWindow().setContentView(view);
2691        initWindowDecorActionBar();
2692    }
2693
2694    /**
2695     * Set the activity content to an explicit view.  This view is placed
2696     * directly into the activity's view hierarchy.  It can itself be a complex
2697     * view hierarchy.
2698     *
2699     * @param view The desired content to display.
2700     * @param params Layout parameters for the view.
2701     *
2702     * @see #setContentView(android.view.View)
2703     * @see #setContentView(int)
2704     */
2705    public void setContentView(View view, ViewGroup.LayoutParams params) {
2706        getWindow().setContentView(view, params);
2707        initWindowDecorActionBar();
2708    }
2709
2710    /**
2711     * Add an additional content view to the activity.  Added after any existing
2712     * ones in the activity -- existing views are NOT removed.
2713     *
2714     * @param view The desired content to display.
2715     * @param params Layout parameters for the view.
2716     */
2717    public void addContentView(View view, ViewGroup.LayoutParams params) {
2718        getWindow().addContentView(view, params);
2719        initWindowDecorActionBar();
2720    }
2721
2722    /**
2723     * Retrieve the {@link TransitionManager} responsible for default transitions in this window.
2724     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
2725     *
2726     * <p>This method will return non-null after content has been initialized (e.g. by using
2727     * {@link #setContentView}) if {@link Window#FEATURE_CONTENT_TRANSITIONS} has been granted.</p>
2728     *
2729     * @return This window's content TransitionManager or null if none is set.
2730     */
2731    public TransitionManager getContentTransitionManager() {
2732        return getWindow().getTransitionManager();
2733    }
2734
2735    /**
2736     * Set the {@link TransitionManager} to use for default transitions in this window.
2737     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
2738     *
2739     * @param tm The TransitionManager to use for scene changes.
2740     */
2741    public void setContentTransitionManager(TransitionManager tm) {
2742        getWindow().setTransitionManager(tm);
2743    }
2744
2745    /**
2746     * Retrieve the {@link Scene} representing this window's current content.
2747     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
2748     *
2749     * <p>This method will return null if the current content is not represented by a Scene.</p>
2750     *
2751     * @return Current Scene being shown or null
2752     */
2753    public Scene getContentScene() {
2754        return getWindow().getContentScene();
2755    }
2756
2757    /**
2758     * Sets whether this activity is finished when touched outside its window's
2759     * bounds.
2760     */
2761    public void setFinishOnTouchOutside(boolean finish) {
2762        mWindow.setCloseOnTouchOutside(finish);
2763    }
2764
2765    /** @hide */
2766    @IntDef(prefix = { "DEFAULT_KEYS_" }, value = {
2767            DEFAULT_KEYS_DISABLE,
2768            DEFAULT_KEYS_DIALER,
2769            DEFAULT_KEYS_SHORTCUT,
2770            DEFAULT_KEYS_SEARCH_LOCAL,
2771            DEFAULT_KEYS_SEARCH_GLOBAL
2772    })
2773    @Retention(RetentionPolicy.SOURCE)
2774    @interface DefaultKeyMode {}
2775
2776    /**
2777     * Use with {@link #setDefaultKeyMode} to turn off default handling of
2778     * keys.
2779     *
2780     * @see #setDefaultKeyMode
2781     */
2782    static public final int DEFAULT_KEYS_DISABLE = 0;
2783    /**
2784     * Use with {@link #setDefaultKeyMode} to launch the dialer during default
2785     * key handling.
2786     *
2787     * @see #setDefaultKeyMode
2788     */
2789    static public final int DEFAULT_KEYS_DIALER = 1;
2790    /**
2791     * Use with {@link #setDefaultKeyMode} to execute a menu shortcut in
2792     * default key handling.
2793     *
2794     * <p>That is, the user does not need to hold down the menu key to execute menu shortcuts.
2795     *
2796     * @see #setDefaultKeyMode
2797     */
2798    static public final int DEFAULT_KEYS_SHORTCUT = 2;
2799    /**
2800     * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes
2801     * will start an application-defined search.  (If the application or activity does not
2802     * actually define a search, the the keys will be ignored.)
2803     *
2804     * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details.
2805     *
2806     * @see #setDefaultKeyMode
2807     */
2808    static public final int DEFAULT_KEYS_SEARCH_LOCAL = 3;
2809
2810    /**
2811     * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes
2812     * will start a global search (typically web search, but some platforms may define alternate
2813     * methods for global search)
2814     *
2815     * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details.
2816     *
2817     * @see #setDefaultKeyMode
2818     */
2819    static public final int DEFAULT_KEYS_SEARCH_GLOBAL = 4;
2820
2821    /**
2822     * Select the default key handling for this activity.  This controls what
2823     * will happen to key events that are not otherwise handled.  The default
2824     * mode ({@link #DEFAULT_KEYS_DISABLE}) will simply drop them on the
2825     * floor. Other modes allow you to launch the dialer
2826     * ({@link #DEFAULT_KEYS_DIALER}), execute a shortcut in your options
2827     * menu without requiring the menu key be held down
2828     * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL}
2829     * and {@link #DEFAULT_KEYS_SEARCH_GLOBAL}).
2830     *
2831     * <p>Note that the mode selected here does not impact the default
2832     * handling of system keys, such as the "back" and "menu" keys, and your
2833     * activity and its views always get a first chance to receive and handle
2834     * all application keys.
2835     *
2836     * @param mode The desired default key mode constant.
2837     *
2838     * @see #onKeyDown
2839     */
2840    public final void setDefaultKeyMode(@DefaultKeyMode int mode) {
2841        mDefaultKeyMode = mode;
2842
2843        // Some modes use a SpannableStringBuilder to track & dispatch input events
2844        // This list must remain in sync with the switch in onKeyDown()
2845        switch (mode) {
2846        case DEFAULT_KEYS_DISABLE:
2847        case DEFAULT_KEYS_SHORTCUT:
2848            mDefaultKeySsb = null;      // not used in these modes
2849            break;
2850        case DEFAULT_KEYS_DIALER:
2851        case DEFAULT_KEYS_SEARCH_LOCAL:
2852        case DEFAULT_KEYS_SEARCH_GLOBAL:
2853            mDefaultKeySsb = new SpannableStringBuilder();
2854            Selection.setSelection(mDefaultKeySsb,0);
2855            break;
2856        default:
2857            throw new IllegalArgumentException();
2858        }
2859    }
2860
2861    /**
2862     * Called when a key was pressed down and not handled by any of the views
2863     * inside of the activity. So, for example, key presses while the cursor
2864     * is inside a TextView will not trigger the event (unless it is a navigation
2865     * to another object) because TextView handles its own key presses.
2866     *
2867     * <p>If the focused view didn't want this event, this method is called.
2868     *
2869     * <p>The default implementation takes care of {@link KeyEvent#KEYCODE_BACK}
2870     * by calling {@link #onBackPressed()}, though the behavior varies based
2871     * on the application compatibility mode: for
2872     * {@link android.os.Build.VERSION_CODES#ECLAIR} or later applications,
2873     * it will set up the dispatch to call {@link #onKeyUp} where the action
2874     * will be performed; for earlier applications, it will perform the
2875     * action immediately in on-down, as those versions of the platform
2876     * behaved.
2877     *
2878     * <p>Other additional default key handling may be performed
2879     * if configured with {@link #setDefaultKeyMode}.
2880     *
2881     * @return Return <code>true</code> to prevent this event from being propagated
2882     * further, or <code>false</code> to indicate that you have not handled
2883     * this event and it should continue to be propagated.
2884     * @see #onKeyUp
2885     * @see android.view.KeyEvent
2886     */
2887    public boolean onKeyDown(int keyCode, KeyEvent event)  {
2888        if (keyCode == KeyEvent.KEYCODE_BACK) {
2889            if (getApplicationInfo().targetSdkVersion
2890                    >= Build.VERSION_CODES.ECLAIR) {
2891                event.startTracking();
2892            } else {
2893                onBackPressed();
2894            }
2895            return true;
2896        }
2897
2898        if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) {
2899            return false;
2900        } else if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) {
2901            Window w = getWindow();
2902            if (w.hasFeature(Window.FEATURE_OPTIONS_PANEL) &&
2903                    w.performPanelShortcut(Window.FEATURE_OPTIONS_PANEL, keyCode, event,
2904                            Menu.FLAG_ALWAYS_PERFORM_CLOSE)) {
2905                return true;
2906            }
2907            return false;
2908        } else if (keyCode == KeyEvent.KEYCODE_TAB) {
2909            // Don't consume TAB here since it's used for navigation. Arrow keys
2910            // aren't considered "typing keys" so they already won't get consumed.
2911            return false;
2912        } else {
2913            // Common code for DEFAULT_KEYS_DIALER & DEFAULT_KEYS_SEARCH_*
2914            boolean clearSpannable = false;
2915            boolean handled;
2916            if ((event.getRepeatCount() != 0) || event.isSystem()) {
2917                clearSpannable = true;
2918                handled = false;
2919            } else {
2920                handled = TextKeyListener.getInstance().onKeyDown(
2921                        null, mDefaultKeySsb, keyCode, event);
2922                if (handled && mDefaultKeySsb.length() > 0) {
2923                    // something useable has been typed - dispatch it now.
2924
2925                    final String str = mDefaultKeySsb.toString();
2926                    clearSpannable = true;
2927
2928                    switch (mDefaultKeyMode) {
2929                    case DEFAULT_KEYS_DIALER:
2930                        Intent intent = new Intent(Intent.ACTION_DIAL,  Uri.parse("tel:" + str));
2931                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2932                        startActivity(intent);
2933                        break;
2934                    case DEFAULT_KEYS_SEARCH_LOCAL:
2935                        startSearch(str, false, null, false);
2936                        break;
2937                    case DEFAULT_KEYS_SEARCH_GLOBAL:
2938                        startSearch(str, false, null, true);
2939                        break;
2940                    }
2941                }
2942            }
2943            if (clearSpannable) {
2944                mDefaultKeySsb.clear();
2945                mDefaultKeySsb.clearSpans();
2946                Selection.setSelection(mDefaultKeySsb,0);
2947            }
2948            return handled;
2949        }
2950    }
2951
2952    /**
2953     * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
2954     * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
2955     * the event).
2956     */
2957    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
2958        return false;
2959    }
2960
2961    /**
2962     * Called when a key was released and not handled by any of the views
2963     * inside of the activity. So, for example, key presses while the cursor
2964     * is inside a TextView will not trigger the event (unless it is a navigation
2965     * to another object) because TextView handles its own key presses.
2966     *
2967     * <p>The default implementation handles KEYCODE_BACK to stop the activity
2968     * and go back.
2969     *
2970     * @return Return <code>true</code> to prevent this event from being propagated
2971     * further, or <code>false</code> to indicate that you have not handled
2972     * this event and it should continue to be propagated.
2973     * @see #onKeyDown
2974     * @see KeyEvent
2975     */
2976    public boolean onKeyUp(int keyCode, KeyEvent event) {
2977        if (getApplicationInfo().targetSdkVersion
2978                >= Build.VERSION_CODES.ECLAIR) {
2979            if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
2980                    && !event.isCanceled()) {
2981                onBackPressed();
2982                return true;
2983            }
2984        }
2985        return false;
2986    }
2987
2988    /**
2989     * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
2990     * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle
2991     * the event).
2992     */
2993    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
2994        return false;
2995    }
2996
2997    /**
2998     * Called when the activity has detected the user's press of the back
2999     * key.  The default implementation simply finishes the current activity,
3000     * but you can override this to do whatever you want.
3001     */
3002    public void onBackPressed() {
3003        if (mActionBar != null && mActionBar.collapseActionView()) {
3004            return;
3005        }
3006
3007        FragmentManager fragmentManager = mFragments.getFragmentManager();
3008
3009        if (fragmentManager.isStateSaved() || !fragmentManager.popBackStackImmediate()) {
3010            finishAfterTransition();
3011        }
3012    }
3013
3014    /**
3015     * Called when a key shortcut event is not handled by any of the views in the Activity.
3016     * Override this method to implement global key shortcuts for the Activity.
3017     * Key shortcuts can also be implemented by setting the
3018     * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items.
3019     *
3020     * @param keyCode The value in event.getKeyCode().
3021     * @param event Description of the key event.
3022     * @return True if the key shortcut was handled.
3023     */
3024    public boolean onKeyShortcut(int keyCode, KeyEvent event) {
3025        // Let the Action Bar have a chance at handling the shortcut.
3026        ActionBar actionBar = getActionBar();
3027        return (actionBar != null && actionBar.onKeyShortcut(keyCode, event));
3028    }
3029
3030    /**
3031     * Called when a touch screen event was not handled by any of the views
3032     * under it.  This is most useful to process touch events that happen
3033     * outside of your window bounds, where there is no view to receive it.
3034     *
3035     * @param event The touch screen event being processed.
3036     *
3037     * @return Return true if you have consumed the event, false if you haven't.
3038     * The default implementation always returns false.
3039     */
3040    public boolean onTouchEvent(MotionEvent event) {
3041        if (mWindow.shouldCloseOnTouch(this, event)) {
3042            finish();
3043            return true;
3044        }
3045
3046        return false;
3047    }
3048
3049    /**
3050     * Called when the trackball was moved and not handled by any of the
3051     * views inside of the activity.  So, for example, if the trackball moves
3052     * while focus is on a button, you will receive a call here because
3053     * buttons do not normally do anything with trackball events.  The call
3054     * here happens <em>before</em> trackball movements are converted to
3055     * DPAD key events, which then get sent back to the view hierarchy, and
3056     * will be processed at the point for things like focus navigation.
3057     *
3058     * @param event The trackball event being processed.
3059     *
3060     * @return Return true if you have consumed the event, false if you haven't.
3061     * The default implementation always returns false.
3062     */
3063    public boolean onTrackballEvent(MotionEvent event) {
3064        return false;
3065    }
3066
3067    /**
3068     * Called when a generic motion event was not handled by any of the
3069     * views inside of the activity.
3070     * <p>
3071     * Generic motion events describe joystick movements, mouse hovers, track pad
3072     * touches, scroll wheel movements and other input events.  The
3073     * {@link MotionEvent#getSource() source} of the motion event specifies
3074     * the class of input that was received.  Implementations of this method
3075     * must examine the bits in the source before processing the event.
3076     * The following code example shows how this is done.
3077     * </p><p>
3078     * Generic motion events with source class
3079     * {@link android.view.InputDevice#SOURCE_CLASS_POINTER}
3080     * are delivered to the view under the pointer.  All other generic motion events are
3081     * delivered to the focused view.
3082     * </p><p>
3083     * See {@link View#onGenericMotionEvent(MotionEvent)} for an example of how to
3084     * handle this event.
3085     * </p>
3086     *
3087     * @param event The generic motion event being processed.
3088     *
3089     * @return Return true if you have consumed the event, false if you haven't.
3090     * The default implementation always returns false.
3091     */
3092    public boolean onGenericMotionEvent(MotionEvent event) {
3093        return false;
3094    }
3095
3096    /**
3097     * Called whenever a key, touch, or trackball event is dispatched to the
3098     * activity.  Implement this method if you wish to know that the user has
3099     * interacted with the device in some way while your activity is running.
3100     * This callback and {@link #onUserLeaveHint} are intended to help
3101     * activities manage status bar notifications intelligently; specifically,
3102     * for helping activities determine the proper time to cancel a notfication.
3103     *
3104     * <p>All calls to your activity's {@link #onUserLeaveHint} callback will
3105     * be accompanied by calls to {@link #onUserInteraction}.  This
3106     * ensures that your activity will be told of relevant user activity such
3107     * as pulling down the notification pane and touching an item there.
3108     *
3109     * <p>Note that this callback will be invoked for the touch down action
3110     * that begins a touch gesture, but may not be invoked for the touch-moved
3111     * and touch-up actions that follow.
3112     *
3113     * @see #onUserLeaveHint()
3114     */
3115    public void onUserInteraction() {
3116    }
3117
3118    public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
3119        // Update window manager if: we have a view, that view is
3120        // attached to its parent (which will be a RootView), and
3121        // this activity is not embedded.
3122        if (mParent == null) {
3123            View decor = mDecor;
3124            if (decor != null && decor.getParent() != null) {
3125                getWindowManager().updateViewLayout(decor, params);
3126            }
3127        }
3128    }
3129
3130    public void onContentChanged() {
3131    }
3132
3133    /**
3134     * Called when the current {@link Window} of the activity gains or loses
3135     * focus.  This is the best indicator of whether this activity is visible
3136     * to the user.  The default implementation clears the key tracking
3137     * state, so should always be called.
3138     *
3139     * <p>Note that this provides information about global focus state, which
3140     * is managed independently of activity lifecycles.  As such, while focus
3141     * changes will generally have some relation to lifecycle changes (an
3142     * activity that is stopped will not generally get window focus), you
3143     * should not rely on any particular order between the callbacks here and
3144     * those in the other lifecycle methods such as {@link #onResume}.
3145     *
3146     * <p>As a general rule, however, a resumed activity will have window
3147     * focus...  unless it has displayed other dialogs or popups that take
3148     * input focus, in which case the activity itself will not have focus
3149     * when the other windows have it.  Likewise, the system may display
3150     * system-level windows (such as the status bar notification panel or
3151     * a system alert) which will temporarily take window input focus without
3152     * pausing the foreground activity.
3153     *
3154     * @param hasFocus Whether the window of this activity has focus.
3155     *
3156     * @see #hasWindowFocus()
3157     * @see #onResume
3158     * @see View#onWindowFocusChanged(boolean)
3159     */
3160    public void onWindowFocusChanged(boolean hasFocus) {
3161    }
3162
3163    /**
3164     * Called when the main window associated with the activity has been
3165     * attached to the window manager.
3166     * See {@link View#onAttachedToWindow() View.onAttachedToWindow()}
3167     * for more information.
3168     * @see View#onAttachedToWindow
3169     */
3170    public void onAttachedToWindow() {
3171    }
3172
3173    /**
3174     * Called when the main window associated with the activity has been
3175     * detached from the window manager.
3176     * See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()}
3177     * for more information.
3178     * @see View#onDetachedFromWindow
3179     */
3180    public void onDetachedFromWindow() {
3181    }
3182
3183    /**
3184     * Returns true if this activity's <em>main</em> window currently has window focus.
3185     * Note that this is not the same as the view itself having focus.
3186     *
3187     * @return True if this activity's main window currently has window focus.
3188     *
3189     * @see #onWindowAttributesChanged(android.view.WindowManager.LayoutParams)
3190     */
3191    public boolean hasWindowFocus() {
3192        Window w = getWindow();
3193        if (w != null) {
3194            View d = w.getDecorView();
3195            if (d != null) {
3196                return d.hasWindowFocus();
3197            }
3198        }
3199        return false;
3200    }
3201
3202    /**
3203     * Called when the main window associated with the activity has been dismissed.
3204     * @hide
3205     */
3206    @Override
3207    public void onWindowDismissed(boolean finishTask, boolean suppressWindowTransition) {
3208        finish(finishTask ? FINISH_TASK_WITH_ACTIVITY : DONT_FINISH_TASK_WITH_ACTIVITY);
3209        if (suppressWindowTransition) {
3210            overridePendingTransition(0, 0);
3211        }
3212    }
3213
3214
3215    /**
3216     * Moves the activity from
3217     * {@link android.app.ActivityManager.StackId#FREEFORM_WORKSPACE_STACK_ID} to
3218     * {@link android.app.ActivityManager.StackId#FULLSCREEN_WORKSPACE_STACK_ID} stack.
3219     *
3220     * @hide
3221     */
3222    @Override
3223    public void exitFreeformMode() throws RemoteException {
3224        ActivityManager.getService().exitFreeformMode(mToken);
3225    }
3226
3227    /** Returns the current stack Id for the window.
3228     * @hide
3229     */
3230    @Override
3231    public int getWindowStackId() throws RemoteException {
3232        return ActivityManager.getService().getActivityStackId(mToken);
3233    }
3234
3235    /**
3236     * Puts the activity in picture-in-picture mode if the activity supports.
3237     * @see android.R.attr#supportsPictureInPicture
3238     * @hide
3239     */
3240    @Override
3241    public void enterPictureInPictureModeIfPossible() {
3242        if (mActivityInfo.supportsPictureInPicture()) {
3243            enterPictureInPictureMode();
3244        }
3245    }
3246
3247    /**
3248     * Called to process key events.  You can override this to intercept all
3249     * key events before they are dispatched to the window.  Be sure to call
3250     * this implementation for key events that should be handled normally.
3251     *
3252     * @param event The key event.
3253     *
3254     * @return boolean Return true if this event was consumed.
3255     */
3256    public boolean dispatchKeyEvent(KeyEvent event) {
3257        onUserInteraction();
3258
3259        // Let action bars open menus in response to the menu key prioritized over
3260        // the window handling it
3261        final int keyCode = event.getKeyCode();
3262        if (keyCode == KeyEvent.KEYCODE_MENU &&
3263                mActionBar != null && mActionBar.onMenuKeyEvent(event)) {
3264            return true;
3265        }
3266
3267        Window win = getWindow();
3268        if (win.superDispatchKeyEvent(event)) {
3269            return true;
3270        }
3271        View decor = mDecor;
3272        if (decor == null) decor = win.getDecorView();
3273        return event.dispatch(this, decor != null
3274                ? decor.getKeyDispatcherState() : null, this);
3275    }
3276
3277    /**
3278     * Called to process a key shortcut event.
3279     * You can override this to intercept all key shortcut events before they are
3280     * dispatched to the window.  Be sure to call this implementation for key shortcut
3281     * events that should be handled normally.
3282     *
3283     * @param event The key shortcut event.
3284     * @return True if this event was consumed.
3285     */
3286    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
3287        onUserInteraction();
3288        if (getWindow().superDispatchKeyShortcutEvent(event)) {
3289            return true;
3290        }
3291        return onKeyShortcut(event.getKeyCode(), event);
3292    }
3293
3294    /**
3295     * Called to process touch screen events.  You can override this to
3296     * intercept all touch screen events before they are dispatched to the
3297     * window.  Be sure to call this implementation for touch screen events
3298     * that should be handled normally.
3299     *
3300     * @param ev The touch screen event.
3301     *
3302     * @return boolean Return true if this event was consumed.
3303     */
3304    public boolean dispatchTouchEvent(MotionEvent ev) {
3305        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
3306            onUserInteraction();
3307        }
3308        if (getWindow().superDispatchTouchEvent(ev)) {
3309            return true;
3310        }
3311        return onTouchEvent(ev);
3312    }
3313
3314    /**
3315     * Called to process trackball events.  You can override this to
3316     * intercept all trackball events before they are dispatched to the
3317     * window.  Be sure to call this implementation for trackball events
3318     * that should be handled normally.
3319     *
3320     * @param ev The trackball event.
3321     *
3322     * @return boolean Return true if this event was consumed.
3323     */
3324    public boolean dispatchTrackballEvent(MotionEvent ev) {
3325        onUserInteraction();
3326        if (getWindow().superDispatchTrackballEvent(ev)) {
3327            return true;
3328        }
3329        return onTrackballEvent(ev);
3330    }
3331
3332    /**
3333     * Called to process generic motion events.  You can override this to
3334     * intercept all generic motion events before they are dispatched to the
3335     * window.  Be sure to call this implementation for generic motion events
3336     * that should be handled normally.
3337     *
3338     * @param ev The generic motion event.
3339     *
3340     * @return boolean Return true if this event was consumed.
3341     */
3342    public boolean dispatchGenericMotionEvent(MotionEvent ev) {
3343        onUserInteraction();
3344        if (getWindow().superDispatchGenericMotionEvent(ev)) {
3345            return true;
3346        }
3347        return onGenericMotionEvent(ev);
3348    }
3349
3350    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
3351        event.setClassName(getClass().getName());
3352        event.setPackageName(getPackageName());
3353
3354        LayoutParams params = getWindow().getAttributes();
3355        boolean isFullScreen = (params.width == LayoutParams.MATCH_PARENT) &&
3356            (params.height == LayoutParams.MATCH_PARENT);
3357        event.setFullScreen(isFullScreen);
3358
3359        CharSequence title = getTitle();
3360        if (!TextUtils.isEmpty(title)) {
3361           event.getText().add(title);
3362        }
3363
3364        return true;
3365    }
3366
3367    /**
3368     * Default implementation of
3369     * {@link android.view.Window.Callback#onCreatePanelView}
3370     * for activities. This
3371     * simply returns null so that all panel sub-windows will have the default
3372     * menu behavior.
3373     */
3374    @Nullable
3375    public View onCreatePanelView(int featureId) {
3376        return null;
3377    }
3378
3379    /**
3380     * Default implementation of
3381     * {@link android.view.Window.Callback#onCreatePanelMenu}
3382     * for activities.  This calls through to the new
3383     * {@link #onCreateOptionsMenu} method for the
3384     * {@link android.view.Window#FEATURE_OPTIONS_PANEL} panel,
3385     * so that subclasses of Activity don't need to deal with feature codes.
3386     */
3387    public boolean onCreatePanelMenu(int featureId, Menu menu) {
3388        if (featureId == Window.FEATURE_OPTIONS_PANEL) {
3389            boolean show = onCreateOptionsMenu(menu);
3390            show |= mFragments.dispatchCreateOptionsMenu(menu, getMenuInflater());
3391            return show;
3392        }
3393        return false;
3394    }
3395
3396    /**
3397     * Default implementation of
3398     * {@link android.view.Window.Callback#onPreparePanel}
3399     * for activities.  This
3400     * calls through to the new {@link #onPrepareOptionsMenu} method for the
3401     * {@link android.view.Window#FEATURE_OPTIONS_PANEL}
3402     * panel, so that subclasses of
3403     * Activity don't need to deal with feature codes.
3404     */
3405    public boolean onPreparePanel(int featureId, View view, Menu menu) {
3406        if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) {
3407            boolean goforit = onPrepareOptionsMenu(menu);
3408            goforit |= mFragments.dispatchPrepareOptionsMenu(menu);
3409            return goforit;
3410        }
3411        return true;
3412    }
3413
3414    /**
3415     * {@inheritDoc}
3416     *
3417     * @return The default implementation returns true.
3418     */
3419    public boolean onMenuOpened(int featureId, Menu menu) {
3420        if (featureId == Window.FEATURE_ACTION_BAR) {
3421            initWindowDecorActionBar();
3422            if (mActionBar != null) {
3423                mActionBar.dispatchMenuVisibilityChanged(true);
3424            } else {
3425                Log.e(TAG, "Tried to open action bar menu with no action bar");
3426            }
3427        }
3428        return true;
3429    }
3430
3431    /**
3432     * Default implementation of
3433     * {@link android.view.Window.Callback#onMenuItemSelected}
3434     * for activities.  This calls through to the new
3435     * {@link #onOptionsItemSelected} method for the
3436     * {@link android.view.Window#FEATURE_OPTIONS_PANEL}
3437     * panel, so that subclasses of
3438     * Activity don't need to deal with feature codes.
3439     */
3440    public boolean onMenuItemSelected(int featureId, MenuItem item) {
3441        CharSequence titleCondensed = item.getTitleCondensed();
3442
3443        switch (featureId) {
3444            case Window.FEATURE_OPTIONS_PANEL:
3445                // Put event logging here so it gets called even if subclass
3446                // doesn't call through to superclass's implmeentation of each
3447                // of these methods below
3448                if(titleCondensed != null) {
3449                    EventLog.writeEvent(50000, 0, titleCondensed.toString());
3450                }
3451                if (onOptionsItemSelected(item)) {
3452                    return true;
3453                }
3454                if (mFragments.dispatchOptionsItemSelected(item)) {
3455                    return true;
3456                }
3457                if (item.getItemId() == android.R.id.home && mActionBar != null &&
3458                        (mActionBar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
3459                    if (mParent == null) {
3460                        return onNavigateUp();
3461                    } else {
3462                        return mParent.onNavigateUpFromChild(this);
3463                    }
3464                }
3465                return false;
3466
3467            case Window.FEATURE_CONTEXT_MENU:
3468                if(titleCondensed != null) {
3469                    EventLog.writeEvent(50000, 1, titleCondensed.toString());
3470                }
3471                if (onContextItemSelected(item)) {
3472                    return true;
3473                }
3474                return mFragments.dispatchContextItemSelected(item);
3475
3476            default:
3477                return false;
3478        }
3479    }
3480
3481    /**
3482     * Default implementation of
3483     * {@link android.view.Window.Callback#onPanelClosed(int, Menu)} for
3484     * activities. This calls through to {@link #onOptionsMenuClosed(Menu)}
3485     * method for the {@link android.view.Window#FEATURE_OPTIONS_PANEL} panel,
3486     * so that subclasses of Activity don't need to deal with feature codes.
3487     * For context menus ({@link Window#FEATURE_CONTEXT_MENU}), the
3488     * {@link #onContextMenuClosed(Menu)} will be called.
3489     */
3490    public void onPanelClosed(int featureId, Menu menu) {
3491        switch (featureId) {
3492            case Window.FEATURE_OPTIONS_PANEL:
3493                mFragments.dispatchOptionsMenuClosed(menu);
3494                onOptionsMenuClosed(menu);
3495                break;
3496
3497            case Window.FEATURE_CONTEXT_MENU:
3498                onContextMenuClosed(menu);
3499                break;
3500
3501            case Window.FEATURE_ACTION_BAR:
3502                initWindowDecorActionBar();
3503                mActionBar.dispatchMenuVisibilityChanged(false);
3504                break;
3505        }
3506    }
3507
3508    /**
3509     * Declare that the options menu has changed, so should be recreated.
3510     * The {@link #onCreateOptionsMenu(Menu)} method will be called the next
3511     * time it needs to be displayed.
3512     */
3513    public void invalidateOptionsMenu() {
3514        if (mWindow.hasFeature(Window.FEATURE_OPTIONS_PANEL) &&
3515                (mActionBar == null || !mActionBar.invalidateOptionsMenu())) {
3516            mWindow.invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL);
3517        }
3518    }
3519
3520    /**
3521     * Initialize the contents of the Activity's standard options menu.  You
3522     * should place your menu items in to <var>menu</var>.
3523     *
3524     * <p>This is only called once, the first time the options menu is
3525     * displayed.  To update the menu every time it is displayed, see
3526     * {@link #onPrepareOptionsMenu}.
3527     *
3528     * <p>The default implementation populates the menu with standard system
3529     * menu items.  These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that
3530     * they will be correctly ordered with application-defined menu items.
3531     * Deriving classes should always call through to the base implementation.
3532     *
3533     * <p>You can safely hold on to <var>menu</var> (and any items created
3534     * from it), making modifications to it as desired, until the next
3535     * time onCreateOptionsMenu() is called.
3536     *
3537     * <p>When you add items to the menu, you can implement the Activity's
3538     * {@link #onOptionsItemSelected} method to handle them there.
3539     *
3540     * @param menu The options menu in which you place your items.
3541     *
3542     * @return You must return true for the menu to be displayed;
3543     *         if you return false it will not be shown.
3544     *
3545     * @see #onPrepareOptionsMenu
3546     * @see #onOptionsItemSelected
3547     */
3548    public boolean onCreateOptionsMenu(Menu menu) {
3549        if (mParent != null) {
3550            return mParent.onCreateOptionsMenu(menu);
3551        }
3552        return true;
3553    }
3554
3555    /**
3556     * Prepare the Screen's standard options menu to be displayed.  This is
3557     * called right before the menu is shown, every time it is shown.  You can
3558     * use this method to efficiently enable/disable items or otherwise
3559     * dynamically modify the contents.
3560     *
3561     * <p>The default implementation updates the system menu items based on the
3562     * activity's state.  Deriving classes should always call through to the
3563     * base class implementation.
3564     *
3565     * @param menu The options menu as last shown or first initialized by
3566     *             onCreateOptionsMenu().
3567     *
3568     * @return You must return true for the menu to be displayed;
3569     *         if you return false it will not be shown.
3570     *
3571     * @see #onCreateOptionsMenu
3572     */
3573    public boolean onPrepareOptionsMenu(Menu menu) {
3574        if (mParent != null) {
3575            return mParent.onPrepareOptionsMenu(menu);
3576        }
3577        return true;
3578    }
3579
3580    /**
3581     * This hook is called whenever an item in your options menu is selected.
3582     * The default implementation simply returns false to have the normal
3583     * processing happen (calling the item's Runnable or sending a message to
3584     * its Handler as appropriate).  You can use this method for any items
3585     * for which you would like to do processing without those other
3586     * facilities.
3587     *
3588     * <p>Derived classes should call through to the base class for it to
3589     * perform the default menu handling.</p>
3590     *
3591     * @param item The menu item that was selected.
3592     *
3593     * @return boolean Return false to allow normal menu processing to
3594     *         proceed, true to consume it here.
3595     *
3596     * @see #onCreateOptionsMenu
3597     */
3598    public boolean onOptionsItemSelected(MenuItem item) {
3599        if (mParent != null) {
3600            return mParent.onOptionsItemSelected(item);
3601        }
3602        return false;
3603    }
3604
3605    /**
3606     * This method is called whenever the user chooses to navigate Up within your application's
3607     * activity hierarchy from the action bar.
3608     *
3609     * <p>If the attribute {@link android.R.attr#parentActivityName parentActivityName}
3610     * was specified in the manifest for this activity or an activity-alias to it,
3611     * default Up navigation will be handled automatically. If any activity
3612     * along the parent chain requires extra Intent arguments, the Activity subclass
3613     * should override the method {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)}
3614     * to supply those arguments.</p>
3615     *
3616     * <p>See <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a>
3617     * from the developer guide and <a href="{@docRoot}design/patterns/navigation.html">Navigation</a>
3618     * from the design guide for more information about navigating within your app.</p>
3619     *
3620     * <p>See the {@link TaskStackBuilder} class and the Activity methods
3621     * {@link #getParentActivityIntent()}, {@link #shouldUpRecreateTask(Intent)}, and
3622     * {@link #navigateUpTo(Intent)} for help implementing custom Up navigation.
3623     * The AppNavigation sample application in the Android SDK is also available for reference.</p>
3624     *
3625     * @return true if Up navigation completed successfully and this Activity was finished,
3626     *         false otherwise.
3627     */
3628    public boolean onNavigateUp() {
3629        // Automatically handle hierarchical Up navigation if the proper
3630        // metadata is available.
3631        Intent upIntent = getParentActivityIntent();
3632        if (upIntent != null) {
3633            if (mActivityInfo.taskAffinity == null) {
3634                // Activities with a null affinity are special; they really shouldn't
3635                // specify a parent activity intent in the first place. Just finish
3636                // the current activity and call it a day.
3637                finish();
3638            } else if (shouldUpRecreateTask(upIntent)) {
3639                TaskStackBuilder b = TaskStackBuilder.create(this);
3640                onCreateNavigateUpTaskStack(b);
3641                onPrepareNavigateUpTaskStack(b);
3642                b.startActivities();
3643
3644                // We can't finishAffinity if we have a result.
3645                // Fall back and simply finish the current activity instead.
3646                if (mResultCode != RESULT_CANCELED || mResultData != null) {
3647                    // Tell the developer what's going on to avoid hair-pulling.
3648                    Log.i(TAG, "onNavigateUp only finishing topmost activity to return a result");
3649                    finish();
3650                } else {
3651                    finishAffinity();
3652                }
3653            } else {
3654                navigateUpTo(upIntent);
3655            }
3656            return true;
3657        }
3658        return false;
3659    }
3660
3661    /**
3662     * This is called when a child activity of this one attempts to navigate up.
3663     * The default implementation simply calls onNavigateUp() on this activity (the parent).
3664     *
3665     * @param child The activity making the call.
3666     */
3667    public boolean onNavigateUpFromChild(Activity child) {
3668        return onNavigateUp();
3669    }
3670
3671    /**
3672     * Define the synthetic task stack that will be generated during Up navigation from
3673     * a different task.
3674     *
3675     * <p>The default implementation of this method adds the parent chain of this activity
3676     * as specified in the manifest to the supplied {@link TaskStackBuilder}. Applications
3677     * may choose to override this method to construct the desired task stack in a different
3678     * way.</p>
3679     *
3680     * <p>This method will be invoked by the default implementation of {@link #onNavigateUp()}
3681     * if {@link #shouldUpRecreateTask(Intent)} returns true when supplied with the intent
3682     * returned by {@link #getParentActivityIntent()}.</p>
3683     *
3684     * <p>Applications that wish to supply extra Intent parameters to the parent stack defined
3685     * by the manifest should override {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)}.</p>
3686     *
3687     * @param builder An empty TaskStackBuilder - the application should add intents representing
3688     *                the desired task stack
3689     */
3690    public void onCreateNavigateUpTaskStack(TaskStackBuilder builder) {
3691        builder.addParentStack(this);
3692    }
3693
3694    /**
3695     * Prepare the synthetic task stack that will be generated during Up navigation
3696     * from a different task.
3697     *
3698     * <p>This method receives the {@link TaskStackBuilder} with the constructed series of
3699     * Intents as generated by {@link #onCreateNavigateUpTaskStack(TaskStackBuilder)}.
3700     * If any extra data should be added to these intents before launching the new task,
3701     * the application should override this method and add that data here.</p>
3702     *
3703     * @param builder A TaskStackBuilder that has been populated with Intents by
3704     *                onCreateNavigateUpTaskStack.
3705     */
3706    public void onPrepareNavigateUpTaskStack(TaskStackBuilder builder) {
3707    }
3708
3709    /**
3710     * This hook is called whenever the options menu is being closed (either by the user canceling
3711     * the menu with the back/menu button, or when an item is selected).
3712     *
3713     * @param menu The options menu as last shown or first initialized by
3714     *             onCreateOptionsMenu().
3715     */
3716    public void onOptionsMenuClosed(Menu menu) {
3717        if (mParent != null) {
3718            mParent.onOptionsMenuClosed(menu);
3719        }
3720    }
3721
3722    /**
3723     * Programmatically opens the options menu. If the options menu is already
3724     * open, this method does nothing.
3725     */
3726    public void openOptionsMenu() {
3727        if (mWindow.hasFeature(Window.FEATURE_OPTIONS_PANEL) &&
3728                (mActionBar == null || !mActionBar.openOptionsMenu())) {
3729            mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null);
3730        }
3731    }
3732
3733    /**
3734     * Progammatically closes the options menu. If the options menu is already
3735     * closed, this method does nothing.
3736     */
3737    public void closeOptionsMenu() {
3738        if (mWindow.hasFeature(Window.FEATURE_OPTIONS_PANEL) &&
3739                (mActionBar == null || !mActionBar.closeOptionsMenu())) {
3740            mWindow.closePanel(Window.FEATURE_OPTIONS_PANEL);
3741        }
3742    }
3743
3744    /**
3745     * Called when a context menu for the {@code view} is about to be shown.
3746     * Unlike {@link #onCreateOptionsMenu(Menu)}, this will be called every
3747     * time the context menu is about to be shown and should be populated for
3748     * the view (or item inside the view for {@link AdapterView} subclasses,
3749     * this can be found in the {@code menuInfo})).
3750     * <p>
3751     * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an
3752     * item has been selected.
3753     * <p>
3754     * It is not safe to hold onto the context menu after this method returns.
3755     *
3756     */
3757    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
3758    }
3759
3760    /**
3761     * Registers a context menu to be shown for the given view (multiple views
3762     * can show the context menu). This method will set the
3763     * {@link OnCreateContextMenuListener} on the view to this activity, so
3764     * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be
3765     * called when it is time to show the context menu.
3766     *
3767     * @see #unregisterForContextMenu(View)
3768     * @param view The view that should show a context menu.
3769     */
3770    public void registerForContextMenu(View view) {
3771        view.setOnCreateContextMenuListener(this);
3772    }
3773
3774    /**
3775     * Prevents a context menu to be shown for the given view. This method will remove the
3776     * {@link OnCreateContextMenuListener} on the view.
3777     *
3778     * @see #registerForContextMenu(View)
3779     * @param view The view that should stop showing a context menu.
3780     */
3781    public void unregisterForContextMenu(View view) {
3782        view.setOnCreateContextMenuListener(null);
3783    }
3784
3785    /**
3786     * Programmatically opens the context menu for a particular {@code view}.
3787     * The {@code view} should have been added via
3788     * {@link #registerForContextMenu(View)}.
3789     *
3790     * @param view The view to show the context menu for.
3791     */
3792    public void openContextMenu(View view) {
3793        view.showContextMenu();
3794    }
3795
3796    /**
3797     * Programmatically closes the most recently opened context menu, if showing.
3798     */
3799    public void closeContextMenu() {
3800        if (mWindow.hasFeature(Window.FEATURE_CONTEXT_MENU)) {
3801            mWindow.closePanel(Window.FEATURE_CONTEXT_MENU);
3802        }
3803    }
3804
3805    /**
3806     * This hook is called whenever an item in a context menu is selected. The
3807     * default implementation simply returns false to have the normal processing
3808     * happen (calling the item's Runnable or sending a message to its Handler
3809     * as appropriate). You can use this method for any items for which you
3810     * would like to do processing without those other facilities.
3811     * <p>
3812     * Use {@link MenuItem#getMenuInfo()} to get extra information set by the
3813     * View that added this menu item.
3814     * <p>
3815     * Derived classes should call through to the base class for it to perform
3816     * the default menu handling.
3817     *
3818     * @param item The context menu item that was selected.
3819     * @return boolean Return false to allow normal context menu processing to
3820     *         proceed, true to consume it here.
3821     */
3822    public boolean onContextItemSelected(MenuItem item) {
3823        if (mParent != null) {
3824            return mParent.onContextItemSelected(item);
3825        }
3826        return false;
3827    }
3828
3829    /**
3830     * This hook is called whenever the context menu is being closed (either by
3831     * the user canceling the menu with the back/menu button, or when an item is
3832     * selected).
3833     *
3834     * @param menu The context menu that is being closed.
3835     */
3836    public void onContextMenuClosed(Menu menu) {
3837        if (mParent != null) {
3838            mParent.onContextMenuClosed(menu);
3839        }
3840    }
3841
3842    /**
3843     * @deprecated Old no-arguments version of {@link #onCreateDialog(int, Bundle)}.
3844     */
3845    @Deprecated
3846    protected Dialog onCreateDialog(int id) {
3847        return null;
3848    }
3849
3850    /**
3851     * Callback for creating dialogs that are managed (saved and restored) for you
3852     * by the activity.  The default implementation calls through to
3853     * {@link #onCreateDialog(int)} for compatibility.
3854     *
3855     * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
3856     * or later, consider instead using a {@link DialogFragment} instead.</em>
3857     *
3858     * <p>If you use {@link #showDialog(int)}, the activity will call through to
3859     * this method the first time, and hang onto it thereafter.  Any dialog
3860     * that is created by this method will automatically be saved and restored
3861     * for you, including whether it is showing.
3862     *
3863     * <p>If you would like the activity to manage saving and restoring dialogs
3864     * for you, you should override this method and handle any ids that are
3865     * passed to {@link #showDialog}.
3866     *
3867     * <p>If you would like an opportunity to prepare your dialog before it is shown,
3868     * override {@link #onPrepareDialog(int, Dialog, Bundle)}.
3869     *
3870     * @param id The id of the dialog.
3871     * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}.
3872     * @return The dialog.  If you return null, the dialog will not be created.
3873     *
3874     * @see #onPrepareDialog(int, Dialog, Bundle)
3875     * @see #showDialog(int, Bundle)
3876     * @see #dismissDialog(int)
3877     * @see #removeDialog(int)
3878     *
3879     * @deprecated Use the new {@link DialogFragment} class with
3880     * {@link FragmentManager} instead; this is also
3881     * available on older platforms through the Android compatibility package.
3882     */
3883    @Nullable
3884    @Deprecated
3885    protected Dialog onCreateDialog(int id, Bundle args) {
3886        return onCreateDialog(id);
3887    }
3888
3889    /**
3890     * @deprecated Old no-arguments version of
3891     * {@link #onPrepareDialog(int, Dialog, Bundle)}.
3892     */
3893    @Deprecated
3894    protected void onPrepareDialog(int id, Dialog dialog) {
3895        dialog.setOwnerActivity(this);
3896    }
3897
3898    /**
3899     * Provides an opportunity to prepare a managed dialog before it is being
3900     * shown.  The default implementation calls through to
3901     * {@link #onPrepareDialog(int, Dialog)} for compatibility.
3902     *
3903     * <p>
3904     * Override this if you need to update a managed dialog based on the state
3905     * of the application each time it is shown. For example, a time picker
3906     * dialog might want to be updated with the current time. You should call
3907     * through to the superclass's implementation. The default implementation
3908     * will set this Activity as the owner activity on the Dialog.
3909     *
3910     * @param id The id of the managed dialog.
3911     * @param dialog The dialog.
3912     * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}.
3913     * @see #onCreateDialog(int, Bundle)
3914     * @see #showDialog(int)
3915     * @see #dismissDialog(int)
3916     * @see #removeDialog(int)
3917     *
3918     * @deprecated Use the new {@link DialogFragment} class with
3919     * {@link FragmentManager} instead; this is also
3920     * available on older platforms through the Android compatibility package.
3921     */
3922    @Deprecated
3923    protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
3924        onPrepareDialog(id, dialog);
3925    }
3926
3927    /**
3928     * Simple version of {@link #showDialog(int, Bundle)} that does not
3929     * take any arguments.  Simply calls {@link #showDialog(int, Bundle)}
3930     * with null arguments.
3931     *
3932     * @deprecated Use the new {@link DialogFragment} class with
3933     * {@link FragmentManager} instead; this is also
3934     * available on older platforms through the Android compatibility package.
3935     */
3936    @Deprecated
3937    public final void showDialog(int id) {
3938        showDialog(id, null);
3939    }
3940
3941    /**
3942     * Show a dialog managed by this activity.  A call to {@link #onCreateDialog(int, Bundle)}
3943     * will be made with the same id the first time this is called for a given
3944     * id.  From thereafter, the dialog will be automatically saved and restored.
3945     *
3946     * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
3947     * or later, consider instead using a {@link DialogFragment} instead.</em>
3948     *
3949     * <p>Each time a dialog is shown, {@link #onPrepareDialog(int, Dialog, Bundle)} will
3950     * be made to provide an opportunity to do any timely preparation.
3951     *
3952     * @param id The id of the managed dialog.
3953     * @param args Arguments to pass through to the dialog.  These will be saved
3954     * and restored for you.  Note that if the dialog is already created,
3955     * {@link #onCreateDialog(int, Bundle)} will not be called with the new
3956     * arguments but {@link #onPrepareDialog(int, Dialog, Bundle)} will be.
3957     * If you need to rebuild the dialog, call {@link #removeDialog(int)} first.
3958     * @return Returns true if the Dialog was created; false is returned if
3959     * it is not created because {@link #onCreateDialog(int, Bundle)} returns false.
3960     *
3961     * @see Dialog
3962     * @see #onCreateDialog(int, Bundle)
3963     * @see #onPrepareDialog(int, Dialog, Bundle)
3964     * @see #dismissDialog(int)
3965     * @see #removeDialog(int)
3966     *
3967     * @deprecated Use the new {@link DialogFragment} class with
3968     * {@link FragmentManager} instead; this is also
3969     * available on older platforms through the Android compatibility package.
3970     */
3971    @Deprecated
3972    public final boolean showDialog(int id, Bundle args) {
3973        if (mManagedDialogs == null) {
3974            mManagedDialogs = new SparseArray<ManagedDialog>();
3975        }
3976        ManagedDialog md = mManagedDialogs.get(id);
3977        if (md == null) {
3978            md = new ManagedDialog();
3979            md.mDialog = createDialog(id, null, args);
3980            if (md.mDialog == null) {
3981                return false;
3982            }
3983            mManagedDialogs.put(id, md);
3984        }
3985
3986        md.mArgs = args;
3987        onPrepareDialog(id, md.mDialog, args);
3988        md.mDialog.show();
3989        return true;
3990    }
3991
3992    /**
3993     * Dismiss a dialog that was previously shown via {@link #showDialog(int)}.
3994     *
3995     * @param id The id of the managed dialog.
3996     *
3997     * @throws IllegalArgumentException if the id was not previously shown via
3998     *   {@link #showDialog(int)}.
3999     *
4000     * @see #onCreateDialog(int, Bundle)
4001     * @see #onPrepareDialog(int, Dialog, Bundle)
4002     * @see #showDialog(int)
4003     * @see #removeDialog(int)
4004     *
4005     * @deprecated Use the new {@link DialogFragment} class with
4006     * {@link FragmentManager} instead; this is also
4007     * available on older platforms through the Android compatibility package.
4008     */
4009    @Deprecated
4010    public final void dismissDialog(int id) {
4011        if (mManagedDialogs == null) {
4012            throw missingDialog(id);
4013        }
4014
4015        final ManagedDialog md = mManagedDialogs.get(id);
4016        if (md == null) {
4017            throw missingDialog(id);
4018        }
4019        md.mDialog.dismiss();
4020    }
4021
4022    /**
4023     * Creates an exception to throw if a user passed in a dialog id that is
4024     * unexpected.
4025     */
4026    private IllegalArgumentException missingDialog(int id) {
4027        return new IllegalArgumentException("no dialog with id " + id + " was ever "
4028                + "shown via Activity#showDialog");
4029    }
4030
4031    /**
4032     * Removes any internal references to a dialog managed by this Activity.
4033     * If the dialog is showing, it will dismiss it as part of the clean up.
4034     *
4035     * <p>This can be useful if you know that you will never show a dialog again and
4036     * want to avoid the overhead of saving and restoring it in the future.
4037     *
4038     * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, this function
4039     * will not throw an exception if you try to remove an ID that does not
4040     * currently have an associated dialog.</p>
4041     *
4042     * @param id The id of the managed dialog.
4043     *
4044     * @see #onCreateDialog(int, Bundle)
4045     * @see #onPrepareDialog(int, Dialog, Bundle)
4046     * @see #showDialog(int)
4047     * @see #dismissDialog(int)
4048     *
4049     * @deprecated Use the new {@link DialogFragment} class with
4050     * {@link FragmentManager} instead; this is also
4051     * available on older platforms through the Android compatibility package.
4052     */
4053    @Deprecated
4054    public final void removeDialog(int id) {
4055        if (mManagedDialogs != null) {
4056            final ManagedDialog md = mManagedDialogs.get(id);
4057            if (md != null) {
4058                md.mDialog.dismiss();
4059                mManagedDialogs.remove(id);
4060            }
4061        }
4062    }
4063
4064    /**
4065     * This hook is called when the user signals the desire to start a search.
4066     *
4067     * <p>You can use this function as a simple way to launch the search UI, in response to a
4068     * menu item, search button, or other widgets within your activity. Unless overidden,
4069     * calling this function is the same as calling
4070     * {@link #startSearch startSearch(null, false, null, false)}, which launches
4071     * search for the current activity as specified in its manifest, see {@link SearchManager}.
4072     *
4073     * <p>You can override this function to force global search, e.g. in response to a dedicated
4074     * search key, or to block search entirely (by simply returning false).
4075     *
4076     * <p>Note: when running in a {@link Configuration#UI_MODE_TYPE_TELEVISION}, the default
4077     * implementation changes to simply return false and you must supply your own custom
4078     * implementation if you want to support search.</p>
4079     *
4080     * @param searchEvent The {@link SearchEvent} that signaled this search.
4081     * @return Returns {@code true} if search launched, and {@code false} if the activity does
4082     * not respond to search.  The default implementation always returns {@code true}, except
4083     * when in {@link Configuration#UI_MODE_TYPE_TELEVISION} mode where it returns false.
4084     *
4085     * @see android.app.SearchManager
4086     */
4087    public boolean onSearchRequested(@Nullable SearchEvent searchEvent) {
4088        mSearchEvent = searchEvent;
4089        boolean result = onSearchRequested();
4090        mSearchEvent = null;
4091        return result;
4092    }
4093
4094    /**
4095     * @see #onSearchRequested(SearchEvent)
4096     */
4097    public boolean onSearchRequested() {
4098        if ((getResources().getConfiguration().uiMode&Configuration.UI_MODE_TYPE_MASK)
4099                != Configuration.UI_MODE_TYPE_TELEVISION) {
4100            startSearch(null, false, null, false);
4101            return true;
4102        } else {
4103            return false;
4104        }
4105    }
4106
4107    /**
4108     * During the onSearchRequested() callbacks, this function will return the
4109     * {@link SearchEvent} that triggered the callback, if it exists.
4110     *
4111     * @return SearchEvent The SearchEvent that triggered the {@link
4112     *                    #onSearchRequested} callback.
4113     */
4114    public final SearchEvent getSearchEvent() {
4115        return mSearchEvent;
4116    }
4117
4118    /**
4119     * This hook is called to launch the search UI.
4120     *
4121     * <p>It is typically called from onSearchRequested(), either directly from
4122     * Activity.onSearchRequested() or from an overridden version in any given
4123     * Activity.  If your goal is simply to activate search, it is preferred to call
4124     * onSearchRequested(), which may have been overridden elsewhere in your Activity.  If your goal
4125     * is to inject specific data such as context data, it is preferred to <i>override</i>
4126     * onSearchRequested(), so that any callers to it will benefit from the override.
4127     *
4128     * @param initialQuery Any non-null non-empty string will be inserted as
4129     * pre-entered text in the search query box.
4130     * @param selectInitialQuery If true, the initial query will be preselected, which means that
4131     * any further typing will replace it.  This is useful for cases where an entire pre-formed
4132     * query is being inserted.  If false, the selection point will be placed at the end of the
4133     * inserted query.  This is useful when the inserted query is text that the user entered,
4134     * and the user would expect to be able to keep typing.  <i>This parameter is only meaningful
4135     * if initialQuery is a non-empty string.</i>
4136     * @param appSearchData An application can insert application-specific
4137     * context here, in order to improve quality or specificity of its own
4138     * searches.  This data will be returned with SEARCH intent(s).  Null if
4139     * no extra data is required.
4140     * @param globalSearch If false, this will only launch the search that has been specifically
4141     * defined by the application (which is usually defined as a local search).  If no default
4142     * search is defined in the current application or activity, global search will be launched.
4143     * If true, this will always launch a platform-global (e.g. web-based) search instead.
4144     *
4145     * @see android.app.SearchManager
4146     * @see #onSearchRequested
4147     */
4148    public void startSearch(@Nullable String initialQuery, boolean selectInitialQuery,
4149            @Nullable Bundle appSearchData, boolean globalSearch) {
4150        ensureSearchManager();
4151        mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
4152                appSearchData, globalSearch);
4153    }
4154
4155    /**
4156     * Similar to {@link #startSearch}, but actually fires off the search query after invoking
4157     * the search dialog.  Made available for testing purposes.
4158     *
4159     * @param query The query to trigger.  If empty, the request will be ignored.
4160     * @param appSearchData An application can insert application-specific
4161     * context here, in order to improve quality or specificity of its own
4162     * searches.  This data will be returned with SEARCH intent(s).  Null if
4163     * no extra data is required.
4164     */
4165    public void triggerSearch(String query, @Nullable Bundle appSearchData) {
4166        ensureSearchManager();
4167        mSearchManager.triggerSearch(query, getComponentName(), appSearchData);
4168    }
4169
4170    /**
4171     * Request that key events come to this activity. Use this if your
4172     * activity has no views with focus, but the activity still wants
4173     * a chance to process key events.
4174     *
4175     * @see android.view.Window#takeKeyEvents
4176     */
4177    public void takeKeyEvents(boolean get) {
4178        getWindow().takeKeyEvents(get);
4179    }
4180
4181    /**
4182     * Enable extended window features.  This is a convenience for calling
4183     * {@link android.view.Window#requestFeature getWindow().requestFeature()}.
4184     *
4185     * @param featureId The desired feature as defined in
4186     *                  {@link android.view.Window}.
4187     * @return Returns true if the requested feature is supported and now
4188     *         enabled.
4189     *
4190     * @see android.view.Window#requestFeature
4191     */
4192    public final boolean requestWindowFeature(int featureId) {
4193        return getWindow().requestFeature(featureId);
4194    }
4195
4196    /**
4197     * Convenience for calling
4198     * {@link android.view.Window#setFeatureDrawableResource}.
4199     */
4200    public final void setFeatureDrawableResource(int featureId, @DrawableRes int resId) {
4201        getWindow().setFeatureDrawableResource(featureId, resId);
4202    }
4203
4204    /**
4205     * Convenience for calling
4206     * {@link android.view.Window#setFeatureDrawableUri}.
4207     */
4208    public final void setFeatureDrawableUri(int featureId, Uri uri) {
4209        getWindow().setFeatureDrawableUri(featureId, uri);
4210    }
4211
4212    /**
4213     * Convenience for calling
4214     * {@link android.view.Window#setFeatureDrawable(int, Drawable)}.
4215     */
4216    public final void setFeatureDrawable(int featureId, Drawable drawable) {
4217        getWindow().setFeatureDrawable(featureId, drawable);
4218    }
4219
4220    /**
4221     * Convenience for calling
4222     * {@link android.view.Window#setFeatureDrawableAlpha}.
4223     */
4224    public final void setFeatureDrawableAlpha(int featureId, int alpha) {
4225        getWindow().setFeatureDrawableAlpha(featureId, alpha);
4226    }
4227
4228    /**
4229     * Convenience for calling
4230     * {@link android.view.Window#getLayoutInflater}.
4231     */
4232    @NonNull
4233    public LayoutInflater getLayoutInflater() {
4234        return getWindow().getLayoutInflater();
4235    }
4236
4237    /**
4238     * Returns a {@link MenuInflater} with this context.
4239     */
4240    @NonNull
4241    public MenuInflater getMenuInflater() {
4242        // Make sure that action views can get an appropriate theme.
4243        if (mMenuInflater == null) {
4244            initWindowDecorActionBar();
4245            if (mActionBar != null) {
4246                mMenuInflater = new MenuInflater(mActionBar.getThemedContext(), this);
4247            } else {
4248                mMenuInflater = new MenuInflater(this);
4249            }
4250        }
4251        return mMenuInflater;
4252    }
4253
4254    @Override
4255    public void setTheme(int resid) {
4256        super.setTheme(resid);
4257        mWindow.setTheme(resid);
4258    }
4259
4260    @Override
4261    protected void onApplyThemeResource(Resources.Theme theme, @StyleRes int resid,
4262            boolean first) {
4263        if (mParent == null) {
4264            super.onApplyThemeResource(theme, resid, first);
4265        } else {
4266            try {
4267                theme.setTo(mParent.getTheme());
4268            } catch (Exception e) {
4269                // Empty
4270            }
4271            theme.applyStyle(resid, false);
4272        }
4273
4274        // Get the primary color and update the TaskDescription for this activity
4275        TypedArray a = theme.obtainStyledAttributes(
4276                com.android.internal.R.styleable.ActivityTaskDescription);
4277        if (mTaskDescription.getPrimaryColor() == 0) {
4278            int colorPrimary = a.getColor(
4279                    com.android.internal.R.styleable.ActivityTaskDescription_colorPrimary, 0);
4280            if (colorPrimary != 0 && Color.alpha(colorPrimary) == 0xFF) {
4281                mTaskDescription.setPrimaryColor(colorPrimary);
4282            }
4283        }
4284
4285        int colorBackground = a.getColor(
4286                com.android.internal.R.styleable.ActivityTaskDescription_colorBackground, 0);
4287        if (colorBackground != 0 && Color.alpha(colorBackground) == 0xFF) {
4288            mTaskDescription.setBackgroundColor(colorBackground);
4289        }
4290
4291        final int statusBarColor = a.getColor(
4292                com.android.internal.R.styleable.ActivityTaskDescription_statusBarColor, 0);
4293        if (statusBarColor != 0) {
4294            mTaskDescription.setStatusBarColor(statusBarColor);
4295        }
4296
4297        final int navigationBarColor = a.getColor(
4298                com.android.internal.R.styleable.ActivityTaskDescription_navigationBarColor, 0);
4299        if (navigationBarColor != 0) {
4300            mTaskDescription.setNavigationBarColor(navigationBarColor);
4301        }
4302
4303        a.recycle();
4304        setTaskDescription(mTaskDescription);
4305    }
4306
4307    /**
4308     * Requests permissions to be granted to this application. These permissions
4309     * must be requested in your manifest, they should not be granted to your app,
4310     * and they should have protection level {@link android.content.pm.PermissionInfo
4311     * #PROTECTION_DANGEROUS dangerous}, regardless whether they are declared by
4312     * the platform or a third-party app.
4313     * <p>
4314     * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL}
4315     * are granted at install time if requested in the manifest. Signature permissions
4316     * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at
4317     * install time if requested in the manifest and the signature of your app matches
4318     * the signature of the app declaring the permissions.
4319     * </p>
4320     * <p>
4321     * If your app does not have the requested permissions the user will be presented
4322     * with UI for accepting them. After the user has accepted or rejected the
4323     * requested permissions you will receive a callback on {@link
4324     * #onRequestPermissionsResult(int, String[], int[])} reporting whether the
4325     * permissions were granted or not.
4326     * </p>
4327     * <p>
4328     * Note that requesting a permission does not guarantee it will be granted and
4329     * your app should be able to run without having this permission.
4330     * </p>
4331     * <p>
4332     * This method may start an activity allowing the user to choose which permissions
4333     * to grant and which to reject. Hence, you should be prepared that your activity
4334     * may be paused and resumed. Further, granting some permissions may require
4335     * a restart of you application. In such a case, the system will recreate the
4336     * activity stack before delivering the result to {@link
4337     * #onRequestPermissionsResult(int, String[], int[])}.
4338     * </p>
4339     * <p>
4340     * When checking whether you have a permission you should use {@link
4341     * #checkSelfPermission(String)}.
4342     * </p>
4343     * <p>
4344     * Calling this API for permissions already granted to your app would show UI
4345     * to the user to decide whether the app can still hold these permissions. This
4346     * can be useful if the way your app uses data guarded by the permissions
4347     * changes significantly.
4348     * </p>
4349     * <p>
4350     * You cannot request a permission if your activity sets {@link
4351     * android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
4352     * <code>true</code> because in this case the activity would not receive
4353     * result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}.
4354     * </p>
4355     * <p>
4356     * The <a href="http://developer.android.com/samples/RuntimePermissions/index.html">
4357     * RuntimePermissions</a> sample app demonstrates how to use this method to
4358     * request permissions at run time.
4359     * </p>
4360     *
4361     * @param permissions The requested permissions. Must me non-null and not empty.
4362     * @param requestCode Application specific request code to match with a result
4363     *    reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
4364     *    Should be >= 0.
4365     *
4366     * @throws IllegalArgumentException if requestCode is negative.
4367     *
4368     * @see #onRequestPermissionsResult(int, String[], int[])
4369     * @see #checkSelfPermission(String)
4370     * @see #shouldShowRequestPermissionRationale(String)
4371     */
4372    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
4373        if (requestCode < 0) {
4374            throw new IllegalArgumentException("requestCode should be >= 0");
4375        }
4376        if (mHasCurrentPermissionsRequest) {
4377            Log.w(TAG, "Can reqeust only one set of permissions at a time");
4378            // Dispatch the callback with empty arrays which means a cancellation.
4379            onRequestPermissionsResult(requestCode, new String[0], new int[0]);
4380            return;
4381        }
4382        Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
4383        startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
4384        mHasCurrentPermissionsRequest = true;
4385    }
4386
4387    /**
4388     * Callback for the result from requesting permissions. This method
4389     * is invoked for every call on {@link #requestPermissions(String[], int)}.
4390     * <p>
4391     * <strong>Note:</strong> It is possible that the permissions request interaction
4392     * with the user is interrupted. In this case you will receive empty permissions
4393     * and results arrays which should be treated as a cancellation.
4394     * </p>
4395     *
4396     * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
4397     * @param permissions The requested permissions. Never null.
4398     * @param grantResults The grant results for the corresponding permissions
4399     *     which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED}
4400     *     or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
4401     *
4402     * @see #requestPermissions(String[], int)
4403     */
4404    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
4405            @NonNull int[] grantResults) {
4406        /* callback - no nothing */
4407    }
4408
4409    /**
4410     * Gets whether you should show UI with rationale for requesting a permission.
4411     * You should do this only if you do not have the permission and the context in
4412     * which the permission is requested does not clearly communicate to the user
4413     * what would be the benefit from granting this permission.
4414     * <p>
4415     * For example, if you write a camera app, requesting the camera permission
4416     * would be expected by the user and no rationale for why it is requested is
4417     * needed. If however, the app needs location for tagging photos then a non-tech
4418     * savvy user may wonder how location is related to taking photos. In this case
4419     * you may choose to show UI with rationale of requesting this permission.
4420     * </p>
4421     *
4422     * @param permission A permission your app wants to request.
4423     * @return Whether you can show permission rationale UI.
4424     *
4425     * @see #checkSelfPermission(String)
4426     * @see #requestPermissions(String[], int)
4427     * @see #onRequestPermissionsResult(int, String[], int[])
4428     */
4429    public boolean shouldShowRequestPermissionRationale(@NonNull String permission) {
4430        return getPackageManager().shouldShowRequestPermissionRationale(permission);
4431    }
4432
4433    /**
4434     * Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
4435     * with no options.
4436     *
4437     * @param intent The intent to start.
4438     * @param requestCode If >= 0, this code will be returned in
4439     *                    onActivityResult() when the activity exits.
4440     *
4441     * @throws android.content.ActivityNotFoundException
4442     *
4443     * @see #startActivity
4444     */
4445    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
4446        startActivityForResult(intent, requestCode, null);
4447    }
4448
4449    /**
4450     * Launch an activity for which you would like a result when it finished.
4451     * When this activity exits, your
4452     * onActivityResult() method will be called with the given requestCode.
4453     * Using a negative requestCode is the same as calling
4454     * {@link #startActivity} (the activity is not launched as a sub-activity).
4455     *
4456     * <p>Note that this method should only be used with Intent protocols
4457     * that are defined to return a result.  In other protocols (such as
4458     * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
4459     * not get the result when you expect.  For example, if the activity you
4460     * are launching uses {@link Intent#FLAG_ACTIVITY_NEW_TASK}, it will not
4461     * run in your task and thus you will immediately receive a cancel result.
4462     *
4463     * <p>As a special case, if you call startActivityForResult() with a requestCode
4464     * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
4465     * activity, then your window will not be displayed until a result is
4466     * returned back from the started activity.  This is to avoid visible
4467     * flickering when redirecting to another activity.
4468     *
4469     * <p>This method throws {@link android.content.ActivityNotFoundException}
4470     * if there was no Activity found to run the given Intent.
4471     *
4472     * @param intent The intent to start.
4473     * @param requestCode If >= 0, this code will be returned in
4474     *                    onActivityResult() when the activity exits.
4475     * @param options Additional options for how the Activity should be started.
4476     * See {@link android.content.Context#startActivity(Intent, Bundle)}
4477     * Context.startActivity(Intent, Bundle)} for more details.
4478     *
4479     * @throws android.content.ActivityNotFoundException
4480     *
4481     * @see #startActivity
4482     */
4483    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
4484            @Nullable Bundle options) {
4485        if (mParent == null) {
4486            options = transferSpringboardActivityOptions(options);
4487            Instrumentation.ActivityResult ar =
4488                mInstrumentation.execStartActivity(
4489                    this, mMainThread.getApplicationThread(), mToken, this,
4490                    intent, requestCode, options);
4491            if (ar != null) {
4492                mMainThread.sendActivityResult(
4493                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
4494                    ar.getResultData());
4495            }
4496            if (requestCode >= 0) {
4497                // If this start is requesting a result, we can avoid making
4498                // the activity visible until the result is received.  Setting
4499                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
4500                // activity hidden during this time, to avoid flickering.
4501                // This can only be done when a result is requested because
4502                // that guarantees we will get information back when the
4503                // activity is finished, no matter what happens to it.
4504                mStartedActivity = true;
4505            }
4506
4507            cancelInputsAndStartExitTransition(options);
4508            // TODO Consider clearing/flushing other event sources and events for child windows.
4509        } else {
4510            if (options != null) {
4511                mParent.startActivityFromChild(this, intent, requestCode, options);
4512            } else {
4513                // Note we want to go through this method for compatibility with
4514                // existing applications that may have overridden it.
4515                mParent.startActivityFromChild(this, intent, requestCode);
4516            }
4517        }
4518    }
4519
4520    /**
4521     * Cancels pending inputs and if an Activity Transition is to be run, starts the transition.
4522     *
4523     * @param options The ActivityOptions bundle used to start an Activity.
4524     */
4525    private void cancelInputsAndStartExitTransition(Bundle options) {
4526        final View decor = mWindow != null ? mWindow.peekDecorView() : null;
4527        if (decor != null) {
4528            decor.cancelPendingInputEvents();
4529        }
4530        if (options != null && !isTopOfTask()) {
4531            mActivityTransitionState.startExitOutTransition(this, options);
4532        }
4533    }
4534
4535    /**
4536     * Returns whether there are any activity transitions currently running on this
4537     * activity. A return value of {@code true} can mean that either an enter or
4538     * exit transition is running, including whether the background of the activity
4539     * is animating as a part of that transition.
4540     *
4541     * @return true if a transition is currently running on this activity, false otherwise.
4542     */
4543    public boolean isActivityTransitionRunning() {
4544        return mActivityTransitionState.isTransitionRunning();
4545    }
4546
4547    private Bundle transferSpringboardActivityOptions(Bundle options) {
4548        if (options == null && (mWindow != null && !mWindow.isActive())) {
4549            final ActivityOptions activityOptions = getActivityOptions();
4550            if (activityOptions != null &&
4551                    activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
4552                return activityOptions.toBundle();
4553            }
4554        }
4555        return options;
4556    }
4557
4558    /**
4559     * @hide Implement to provide correct calling token.
4560     */
4561    public void startActivityForResultAsUser(Intent intent, int requestCode, UserHandle user) {
4562        startActivityForResultAsUser(intent, requestCode, null, user);
4563    }
4564
4565    /**
4566     * @hide Implement to provide correct calling token.
4567     */
4568    public void startActivityForResultAsUser(Intent intent, int requestCode,
4569            @Nullable Bundle options, UserHandle user) {
4570        startActivityForResultAsUser(intent, mEmbeddedID, requestCode, options, user);
4571    }
4572
4573    /**
4574     * @hide Implement to provide correct calling token.
4575     */
4576    public void startActivityForResultAsUser(Intent intent, String resultWho, int requestCode,
4577            @Nullable Bundle options, UserHandle user) {
4578        if (mParent != null) {
4579            throw new RuntimeException("Can't be called from a child");
4580        }
4581        options = transferSpringboardActivityOptions(options);
4582        Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
4583                this, mMainThread.getApplicationThread(), mToken, resultWho, intent, requestCode,
4584                options, user);
4585        if (ar != null) {
4586            mMainThread.sendActivityResult(
4587                mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
4588        }
4589        if (requestCode >= 0) {
4590            // If this start is requesting a result, we can avoid making
4591            // the activity visible until the result is received.  Setting
4592            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
4593            // activity hidden during this time, to avoid flickering.
4594            // This can only be done when a result is requested because
4595            // that guarantees we will get information back when the
4596            // activity is finished, no matter what happens to it.
4597            mStartedActivity = true;
4598        }
4599
4600        cancelInputsAndStartExitTransition(options);
4601    }
4602
4603    /**
4604     * @hide Implement to provide correct calling token.
4605     */
4606    public void startActivityAsUser(Intent intent, UserHandle user) {
4607        startActivityAsUser(intent, null, user);
4608    }
4609
4610    /**
4611     * @hide Implement to provide correct calling token.
4612     */
4613    public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
4614        if (mParent != null) {
4615            throw new RuntimeException("Can't be called from a child");
4616        }
4617        options = transferSpringboardActivityOptions(options);
4618        Instrumentation.ActivityResult ar =
4619                mInstrumentation.execStartActivity(
4620                        this, mMainThread.getApplicationThread(), mToken, mEmbeddedID,
4621                        intent, -1, options, user);
4622        if (ar != null) {
4623            mMainThread.sendActivityResult(
4624                mToken, mEmbeddedID, -1, ar.getResultCode(),
4625                ar.getResultData());
4626        }
4627        cancelInputsAndStartExitTransition(options);
4628    }
4629
4630    /**
4631     * Start a new activity as if it was started by the activity that started our
4632     * current activity.  This is for the resolver and chooser activities, which operate
4633     * as intermediaries that dispatch their intent to the target the user selects -- to
4634     * do this, they must perform all security checks including permission grants as if
4635     * their launch had come from the original activity.
4636     * @param intent The Intent to start.
4637     * @param options ActivityOptions or null.
4638     * @param ignoreTargetSecurity If true, the activity manager will not check whether the
4639     * caller it is doing the start is, is actually allowed to start the target activity.
4640     * If you set this to true, you must set an explicit component in the Intent and do any
4641     * appropriate security checks yourself.
4642     * @param userId The user the new activity should run as.
4643     * @hide
4644     */
4645    public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
4646            boolean ignoreTargetSecurity, int userId) {
4647        if (mParent != null) {
4648            throw new RuntimeException("Can't be called from a child");
4649        }
4650        options = transferSpringboardActivityOptions(options);
4651        Instrumentation.ActivityResult ar =
4652                mInstrumentation.execStartActivityAsCaller(
4653                        this, mMainThread.getApplicationThread(), mToken, this,
4654                        intent, -1, options, ignoreTargetSecurity, userId);
4655        if (ar != null) {
4656            mMainThread.sendActivityResult(
4657                mToken, mEmbeddedID, -1, ar.getResultCode(),
4658                ar.getResultData());
4659        }
4660        cancelInputsAndStartExitTransition(options);
4661    }
4662
4663    /**
4664     * Same as calling {@link #startIntentSenderForResult(IntentSender, int,
4665     * Intent, int, int, int, Bundle)} with no options.
4666     *
4667     * @param intent The IntentSender to launch.
4668     * @param requestCode If >= 0, this code will be returned in
4669     *                    onActivityResult() when the activity exits.
4670     * @param fillInIntent If non-null, this will be provided as the
4671     * intent parameter to {@link IntentSender#sendIntent}.
4672     * @param flagsMask Intent flags in the original IntentSender that you
4673     * would like to change.
4674     * @param flagsValues Desired values for any bits set in
4675     * <var>flagsMask</var>
4676     * @param extraFlags Always set to 0.
4677     */
4678    public void startIntentSenderForResult(IntentSender intent, int requestCode,
4679            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
4680            throws IntentSender.SendIntentException {
4681        startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
4682                flagsValues, extraFlags, null);
4683    }
4684
4685    /**
4686     * Like {@link #startActivityForResult(Intent, int)}, but allowing you
4687     * to use a IntentSender to describe the activity to be started.  If
4688     * the IntentSender is for an activity, that activity will be started
4689     * as if you had called the regular {@link #startActivityForResult(Intent, int)}
4690     * here; otherwise, its associated action will be executed (such as
4691     * sending a broadcast) as if you had called
4692     * {@link IntentSender#sendIntent IntentSender.sendIntent} on it.
4693     *
4694     * @param intent The IntentSender to launch.
4695     * @param requestCode If >= 0, this code will be returned in
4696     *                    onActivityResult() when the activity exits.
4697     * @param fillInIntent If non-null, this will be provided as the
4698     * intent parameter to {@link IntentSender#sendIntent}.
4699     * @param flagsMask Intent flags in the original IntentSender that you
4700     * would like to change.
4701     * @param flagsValues Desired values for any bits set in
4702     * <var>flagsMask</var>
4703     * @param extraFlags Always set to 0.
4704     * @param options Additional options for how the Activity should be started.
4705     * See {@link android.content.Context#startActivity(Intent, Bundle)}
4706     * Context.startActivity(Intent, Bundle)} for more details.  If options
4707     * have also been supplied by the IntentSender, options given here will
4708     * override any that conflict with those given by the IntentSender.
4709     */
4710    public void startIntentSenderForResult(IntentSender intent, int requestCode,
4711            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
4712            Bundle options) throws IntentSender.SendIntentException {
4713        if (mParent == null) {
4714            startIntentSenderForResultInner(intent, mEmbeddedID, requestCode, fillInIntent,
4715                    flagsMask, flagsValues, options);
4716        } else if (options != null) {
4717            mParent.startIntentSenderFromChild(this, intent, requestCode,
4718                    fillInIntent, flagsMask, flagsValues, extraFlags, options);
4719        } else {
4720            // Note we want to go through this call for compatibility with
4721            // existing applications that may have overridden the method.
4722            mParent.startIntentSenderFromChild(this, intent, requestCode,
4723                    fillInIntent, flagsMask, flagsValues, extraFlags);
4724        }
4725    }
4726
4727    private void startIntentSenderForResultInner(IntentSender intent, String who, int requestCode,
4728            Intent fillInIntent, int flagsMask, int flagsValues,
4729            Bundle options)
4730            throws IntentSender.SendIntentException {
4731        try {
4732            String resolvedType = null;
4733            if (fillInIntent != null) {
4734                fillInIntent.migrateExtraStreamToClipData();
4735                fillInIntent.prepareToLeaveProcess(this);
4736                resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
4737            }
4738            int result = ActivityManager.getService()
4739                .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
4740                        fillInIntent, resolvedType, mToken, who,
4741                        requestCode, flagsMask, flagsValues, options);
4742            if (result == ActivityManager.START_CANCELED) {
4743                throw new IntentSender.SendIntentException();
4744            }
4745            Instrumentation.checkStartActivityResult(result, null);
4746        } catch (RemoteException e) {
4747        }
4748        if (requestCode >= 0) {
4749            // If this start is requesting a result, we can avoid making
4750            // the activity visible until the result is received.  Setting
4751            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
4752            // activity hidden during this time, to avoid flickering.
4753            // This can only be done when a result is requested because
4754            // that guarantees we will get information back when the
4755            // activity is finished, no matter what happens to it.
4756            mStartedActivity = true;
4757        }
4758    }
4759
4760    /**
4761     * Same as {@link #startActivity(Intent, Bundle)} with no options
4762     * specified.
4763     *
4764     * @param intent The intent to start.
4765     *
4766     * @throws android.content.ActivityNotFoundException
4767     *
4768     * @see #startActivity(Intent, Bundle)
4769     * @see #startActivityForResult
4770     */
4771    @Override
4772    public void startActivity(Intent intent) {
4773        this.startActivity(intent, null);
4774    }
4775
4776    /**
4777     * Launch a new activity.  You will not receive any information about when
4778     * the activity exits.  This implementation overrides the base version,
4779     * providing information about
4780     * the activity performing the launch.  Because of this additional
4781     * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
4782     * required; if not specified, the new activity will be added to the
4783     * task of the caller.
4784     *
4785     * <p>This method throws {@link android.content.ActivityNotFoundException}
4786     * if there was no Activity found to run the given Intent.
4787     *
4788     * @param intent The intent to start.
4789     * @param options Additional options for how the Activity should be started.
4790     * See {@link android.content.Context#startActivity(Intent, Bundle)}
4791     * Context.startActivity(Intent, Bundle)} for more details.
4792     *
4793     * @throws android.content.ActivityNotFoundException
4794     *
4795     * @see #startActivity(Intent)
4796     * @see #startActivityForResult
4797     */
4798    @Override
4799    public void startActivity(Intent intent, @Nullable Bundle options) {
4800        if (options != null) {
4801            startActivityForResult(intent, -1, options);
4802        } else {
4803            // Note we want to go through this call for compatibility with
4804            // applications that may have overridden the method.
4805            startActivityForResult(intent, -1);
4806        }
4807    }
4808
4809    /**
4810     * Same as {@link #startActivities(Intent[], Bundle)} with no options
4811     * specified.
4812     *
4813     * @param intents The intents to start.
4814     *
4815     * @throws android.content.ActivityNotFoundException
4816     *
4817     * @see #startActivities(Intent[], Bundle)
4818     * @see #startActivityForResult
4819     */
4820    @Override
4821    public void startActivities(Intent[] intents) {
4822        startActivities(intents, null);
4823    }
4824
4825    /**
4826     * Launch a new activity.  You will not receive any information about when
4827     * the activity exits.  This implementation overrides the base version,
4828     * providing information about
4829     * the activity performing the launch.  Because of this additional
4830     * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
4831     * required; if not specified, the new activity will be added to the
4832     * task of the caller.
4833     *
4834     * <p>This method throws {@link android.content.ActivityNotFoundException}
4835     * if there was no Activity found to run the given Intent.
4836     *
4837     * @param intents The intents to start.
4838     * @param options Additional options for how the Activity should be started.
4839     * See {@link android.content.Context#startActivity(Intent, Bundle)}
4840     * Context.startActivity(Intent, Bundle)} for more details.
4841     *
4842     * @throws android.content.ActivityNotFoundException
4843     *
4844     * @see #startActivities(Intent[])
4845     * @see #startActivityForResult
4846     */
4847    @Override
4848    public void startActivities(Intent[] intents, @Nullable Bundle options) {
4849        mInstrumentation.execStartActivities(this, mMainThread.getApplicationThread(),
4850                mToken, this, intents, options);
4851    }
4852
4853    /**
4854     * Same as calling {@link #startIntentSender(IntentSender, Intent, int, int, int, Bundle)}
4855     * with no options.
4856     *
4857     * @param intent The IntentSender to launch.
4858     * @param fillInIntent If non-null, this will be provided as the
4859     * intent parameter to {@link IntentSender#sendIntent}.
4860     * @param flagsMask Intent flags in the original IntentSender that you
4861     * would like to change.
4862     * @param flagsValues Desired values for any bits set in
4863     * <var>flagsMask</var>
4864     * @param extraFlags Always set to 0.
4865     */
4866    public void startIntentSender(IntentSender intent,
4867            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
4868            throws IntentSender.SendIntentException {
4869        startIntentSender(intent, fillInIntent, flagsMask, flagsValues,
4870                extraFlags, null);
4871    }
4872
4873    /**
4874     * Like {@link #startActivity(Intent, Bundle)}, but taking a IntentSender
4875     * to start; see
4876     * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int, Bundle)}
4877     * for more information.
4878     *
4879     * @param intent The IntentSender to launch.
4880     * @param fillInIntent If non-null, this will be provided as the
4881     * intent parameter to {@link IntentSender#sendIntent}.
4882     * @param flagsMask Intent flags in the original IntentSender that you
4883     * would like to change.
4884     * @param flagsValues Desired values for any bits set in
4885     * <var>flagsMask</var>
4886     * @param extraFlags Always set to 0.
4887     * @param options Additional options for how the Activity should be started.
4888     * See {@link android.content.Context#startActivity(Intent, Bundle)}
4889     * Context.startActivity(Intent, Bundle)} for more details.  If options
4890     * have also been supplied by the IntentSender, options given here will
4891     * override any that conflict with those given by the IntentSender.
4892     */
4893    public void startIntentSender(IntentSender intent,
4894            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
4895            Bundle options) throws IntentSender.SendIntentException {
4896        if (options != null) {
4897            startIntentSenderForResult(intent, -1, fillInIntent, flagsMask,
4898                    flagsValues, extraFlags, options);
4899        } else {
4900            // Note we want to go through this call for compatibility with
4901            // applications that may have overridden the method.
4902            startIntentSenderForResult(intent, -1, fillInIntent, flagsMask,
4903                    flagsValues, extraFlags);
4904        }
4905    }
4906
4907    /**
4908     * Same as calling {@link #startActivityIfNeeded(Intent, int, Bundle)}
4909     * with no options.
4910     *
4911     * @param intent The intent to start.
4912     * @param requestCode If >= 0, this code will be returned in
4913     *         onActivityResult() when the activity exits, as described in
4914     *         {@link #startActivityForResult}.
4915     *
4916     * @return If a new activity was launched then true is returned; otherwise
4917     *         false is returned and you must handle the Intent yourself.
4918     *
4919     * @see #startActivity
4920     * @see #startActivityForResult
4921     */
4922    public boolean startActivityIfNeeded(@RequiresPermission @NonNull Intent intent,
4923            int requestCode) {
4924        return startActivityIfNeeded(intent, requestCode, null);
4925    }
4926
4927    /**
4928     * A special variation to launch an activity only if a new activity
4929     * instance is needed to handle the given Intent.  In other words, this is
4930     * just like {@link #startActivityForResult(Intent, int)} except: if you are
4931     * using the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag, or
4932     * singleTask or singleTop
4933     * {@link android.R.styleable#AndroidManifestActivity_launchMode launchMode},
4934     * and the activity
4935     * that handles <var>intent</var> is the same as your currently running
4936     * activity, then a new instance is not needed.  In this case, instead of
4937     * the normal behavior of calling {@link #onNewIntent} this function will
4938     * return and you can handle the Intent yourself.
4939     *
4940     * <p>This function can only be called from a top-level activity; if it is
4941     * called from a child activity, a runtime exception will be thrown.
4942     *
4943     * @param intent The intent to start.
4944     * @param requestCode If >= 0, this code will be returned in
4945     *         onActivityResult() when the activity exits, as described in
4946     *         {@link #startActivityForResult}.
4947     * @param options Additional options for how the Activity should be started.
4948     * See {@link android.content.Context#startActivity(Intent, Bundle)}
4949     * Context.startActivity(Intent, Bundle)} for more details.
4950     *
4951     * @return If a new activity was launched then true is returned; otherwise
4952     *         false is returned and you must handle the Intent yourself.
4953     *
4954     * @see #startActivity
4955     * @see #startActivityForResult
4956     */
4957    public boolean startActivityIfNeeded(@RequiresPermission @NonNull Intent intent,
4958            int requestCode, @Nullable Bundle options) {
4959        if (mParent == null) {
4960            int result = ActivityManager.START_RETURN_INTENT_TO_CALLER;
4961            try {
4962                Uri referrer = onProvideReferrer();
4963                if (referrer != null) {
4964                    intent.putExtra(Intent.EXTRA_REFERRER, referrer);
4965                }
4966                intent.migrateExtraStreamToClipData();
4967                intent.prepareToLeaveProcess(this);
4968                result = ActivityManager.getService()
4969                    .startActivity(mMainThread.getApplicationThread(), getBasePackageName(),
4970                            intent, intent.resolveTypeIfNeeded(getContentResolver()), mToken,
4971                            mEmbeddedID, requestCode, ActivityManager.START_FLAG_ONLY_IF_NEEDED,
4972                            null, options);
4973            } catch (RemoteException e) {
4974                // Empty
4975            }
4976
4977            Instrumentation.checkStartActivityResult(result, intent);
4978
4979            if (requestCode >= 0) {
4980                // If this start is requesting a result, we can avoid making
4981                // the activity visible until the result is received.  Setting
4982                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
4983                // activity hidden during this time, to avoid flickering.
4984                // This can only be done when a result is requested because
4985                // that guarantees we will get information back when the
4986                // activity is finished, no matter what happens to it.
4987                mStartedActivity = true;
4988            }
4989            return result != ActivityManager.START_RETURN_INTENT_TO_CALLER;
4990        }
4991
4992        throw new UnsupportedOperationException(
4993            "startActivityIfNeeded can only be called from a top-level activity");
4994    }
4995
4996    /**
4997     * Same as calling {@link #startNextMatchingActivity(Intent, Bundle)} with
4998     * no options.
4999     *
5000     * @param intent The intent to dispatch to the next activity.  For
5001     * correct behavior, this must be the same as the Intent that started
5002     * your own activity; the only changes you can make are to the extras
5003     * inside of it.
5004     *
5005     * @return Returns a boolean indicating whether there was another Activity
5006     * to start: true if there was a next activity to start, false if there
5007     * wasn't.  In general, if true is returned you will then want to call
5008     * finish() on yourself.
5009     */
5010    public boolean startNextMatchingActivity(@RequiresPermission @NonNull Intent intent) {
5011        return startNextMatchingActivity(intent, null);
5012    }
5013
5014    /**
5015     * Special version of starting an activity, for use when you are replacing
5016     * other activity components.  You can use this to hand the Intent off
5017     * to the next Activity that can handle it.  You typically call this in
5018     * {@link #onCreate} with the Intent returned by {@link #getIntent}.
5019     *
5020     * @param intent The intent to dispatch to the next activity.  For
5021     * correct behavior, this must be the same as the Intent that started
5022     * your own activity; the only changes you can make are to the extras
5023     * inside of it.
5024     * @param options Additional options for how the Activity should be started.
5025     * See {@link android.content.Context#startActivity(Intent, Bundle)}
5026     * Context.startActivity(Intent, Bundle)} for more details.
5027     *
5028     * @return Returns a boolean indicating whether there was another Activity
5029     * to start: true if there was a next activity to start, false if there
5030     * wasn't.  In general, if true is returned you will then want to call
5031     * finish() on yourself.
5032     */
5033    public boolean startNextMatchingActivity(@RequiresPermission @NonNull Intent intent,
5034            @Nullable Bundle options) {
5035        if (mParent == null) {
5036            try {
5037                intent.migrateExtraStreamToClipData();
5038                intent.prepareToLeaveProcess(this);
5039                return ActivityManager.getService()
5040                    .startNextMatchingActivity(mToken, intent, options);
5041            } catch (RemoteException e) {
5042                // Empty
5043            }
5044            return false;
5045        }
5046
5047        throw new UnsupportedOperationException(
5048            "startNextMatchingActivity can only be called from a top-level activity");
5049    }
5050
5051    /**
5052     * Same as calling {@link #startActivityFromChild(Activity, Intent, int, Bundle)}
5053     * with no options.
5054     *
5055     * @param child The activity making the call.
5056     * @param intent The intent to start.
5057     * @param requestCode Reply request code.  < 0 if reply is not requested.
5058     *
5059     * @throws android.content.ActivityNotFoundException
5060     *
5061     * @see #startActivity
5062     * @see #startActivityForResult
5063     */
5064    public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
5065            int requestCode) {
5066        startActivityFromChild(child, intent, requestCode, null);
5067    }
5068
5069    /**
5070     * This is called when a child activity of this one calls its
5071     * {@link #startActivity} or {@link #startActivityForResult} method.
5072     *
5073     * <p>This method throws {@link android.content.ActivityNotFoundException}
5074     * if there was no Activity found to run the given Intent.
5075     *
5076     * @param child The activity making the call.
5077     * @param intent The intent to start.
5078     * @param requestCode Reply request code.  < 0 if reply is not requested.
5079     * @param options Additional options for how the Activity should be started.
5080     * See {@link android.content.Context#startActivity(Intent, Bundle)}
5081     * Context.startActivity(Intent, Bundle)} for more details.
5082     *
5083     * @throws android.content.ActivityNotFoundException
5084     *
5085     * @see #startActivity
5086     * @see #startActivityForResult
5087     */
5088    public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
5089            int requestCode, @Nullable Bundle options) {
5090        options = transferSpringboardActivityOptions(options);
5091        Instrumentation.ActivityResult ar =
5092            mInstrumentation.execStartActivity(
5093                this, mMainThread.getApplicationThread(), mToken, child,
5094                intent, requestCode, options);
5095        if (ar != null) {
5096            mMainThread.sendActivityResult(
5097                mToken, child.mEmbeddedID, requestCode,
5098                ar.getResultCode(), ar.getResultData());
5099        }
5100        cancelInputsAndStartExitTransition(options);
5101    }
5102
5103    /**
5104     * Same as calling {@link #startActivityFromFragment(Fragment, Intent, int, Bundle)}
5105     * with no options.
5106     *
5107     * @param fragment The fragment making the call.
5108     * @param intent The intent to start.
5109     * @param requestCode Reply request code.  < 0 if reply is not requested.
5110     *
5111     * @throws android.content.ActivityNotFoundException
5112     *
5113     * @see Fragment#startActivity
5114     * @see Fragment#startActivityForResult
5115     */
5116    public void startActivityFromFragment(@NonNull Fragment fragment,
5117            @RequiresPermission Intent intent, int requestCode) {
5118        startActivityFromFragment(fragment, intent, requestCode, null);
5119    }
5120
5121    /**
5122     * This is called when a Fragment in this activity calls its
5123     * {@link Fragment#startActivity} or {@link Fragment#startActivityForResult}
5124     * method.
5125     *
5126     * <p>This method throws {@link android.content.ActivityNotFoundException}
5127     * if there was no Activity found to run the given Intent.
5128     *
5129     * @param fragment The fragment making the call.
5130     * @param intent The intent to start.
5131     * @param requestCode Reply request code.  < 0 if reply is not requested.
5132     * @param options Additional options for how the Activity should be started.
5133     * See {@link android.content.Context#startActivity(Intent, Bundle)}
5134     * Context.startActivity(Intent, Bundle)} for more details.
5135     *
5136     * @throws android.content.ActivityNotFoundException
5137     *
5138     * @see Fragment#startActivity
5139     * @see Fragment#startActivityForResult
5140     */
5141    public void startActivityFromFragment(@NonNull Fragment fragment,
5142            @RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
5143        startActivityForResult(fragment.mWho, intent, requestCode, options);
5144    }
5145
5146    /**
5147     * @hide
5148     */
5149    public void startActivityAsUserFromFragment(@NonNull Fragment fragment,
5150            @RequiresPermission Intent intent, int requestCode, @Nullable Bundle options,
5151            UserHandle user) {
5152        startActivityForResultAsUser(intent, fragment.mWho, requestCode, options, user);
5153    }
5154
5155    /**
5156     * @hide
5157     */
5158    @Override
5159    public void startActivityForResult(
5160            String who, Intent intent, int requestCode, @Nullable Bundle options) {
5161        Uri referrer = onProvideReferrer();
5162        if (referrer != null) {
5163            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
5164        }
5165        options = transferSpringboardActivityOptions(options);
5166        Instrumentation.ActivityResult ar =
5167            mInstrumentation.execStartActivity(
5168                this, mMainThread.getApplicationThread(), mToken, who,
5169                intent, requestCode, options);
5170        if (ar != null) {
5171            mMainThread.sendActivityResult(
5172                mToken, who, requestCode,
5173                ar.getResultCode(), ar.getResultData());
5174        }
5175        cancelInputsAndStartExitTransition(options);
5176    }
5177
5178    /**
5179     * @hide
5180     */
5181    @Override
5182    public boolean canStartActivityForResult() {
5183        return true;
5184    }
5185
5186    /**
5187     * Same as calling {@link #startIntentSenderFromChild(Activity, IntentSender,
5188     * int, Intent, int, int, int, Bundle)} with no options.
5189     */
5190    public void startIntentSenderFromChild(Activity child, IntentSender intent,
5191            int requestCode, Intent fillInIntent, int flagsMask, int flagsValues,
5192            int extraFlags)
5193            throws IntentSender.SendIntentException {
5194        startIntentSenderFromChild(child, intent, requestCode, fillInIntent,
5195                flagsMask, flagsValues, extraFlags, null);
5196    }
5197
5198    /**
5199     * Like {@link #startActivityFromChild(Activity, Intent, int)}, but
5200     * taking a IntentSender; see
5201     * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int)}
5202     * for more information.
5203     */
5204    public void startIntentSenderFromChild(Activity child, IntentSender intent,
5205            int requestCode, Intent fillInIntent, int flagsMask, int flagsValues,
5206            int extraFlags, @Nullable Bundle options)
5207            throws IntentSender.SendIntentException {
5208        startIntentSenderForResultInner(intent, child.mEmbeddedID, requestCode, fillInIntent,
5209                flagsMask, flagsValues, options);
5210    }
5211
5212    /**
5213     * Like {@link #startIntentSenderFromChild}, but taking a Fragment; see
5214     * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int)}
5215     * for more information.
5216     *
5217     * @hide
5218     */
5219    public void startIntentSenderFromChildFragment(Fragment child, IntentSender intent,
5220            int requestCode, Intent fillInIntent, int flagsMask, int flagsValues,
5221            int extraFlags, @Nullable Bundle options)
5222            throws IntentSender.SendIntentException {
5223        startIntentSenderForResultInner(intent, child.mWho, requestCode, fillInIntent,
5224                flagsMask, flagsValues, options);
5225    }
5226
5227    /**
5228     * Call immediately after one of the flavors of {@link #startActivity(Intent)}
5229     * or {@link #finish} to specify an explicit transition animation to
5230     * perform next.
5231     *
5232     * <p>As of {@link android.os.Build.VERSION_CODES#JELLY_BEAN} an alternative
5233     * to using this with starting activities is to supply the desired animation
5234     * information through a {@link ActivityOptions} bundle to
5235     * {@link #startActivity(Intent, Bundle)} or a related function.  This allows
5236     * you to specify a custom animation even when starting an activity from
5237     * outside the context of the current top activity.
5238     *
5239     * @param enterAnim A resource ID of the animation resource to use for
5240     * the incoming activity.  Use 0 for no animation.
5241     * @param exitAnim A resource ID of the animation resource to use for
5242     * the outgoing activity.  Use 0 for no animation.
5243     */
5244    public void overridePendingTransition(int enterAnim, int exitAnim) {
5245        try {
5246            ActivityManager.getService().overridePendingTransition(
5247                    mToken, getPackageName(), enterAnim, exitAnim);
5248        } catch (RemoteException e) {
5249        }
5250    }
5251
5252    /**
5253     * Call this to set the result that your activity will return to its
5254     * caller.
5255     *
5256     * @param resultCode The result code to propagate back to the originating
5257     *                   activity, often RESULT_CANCELED or RESULT_OK
5258     *
5259     * @see #RESULT_CANCELED
5260     * @see #RESULT_OK
5261     * @see #RESULT_FIRST_USER
5262     * @see #setResult(int, Intent)
5263     */
5264    public final void setResult(int resultCode) {
5265        synchronized (this) {
5266            mResultCode = resultCode;
5267            mResultData = null;
5268        }
5269    }
5270
5271    /**
5272     * Call this to set the result that your activity will return to its
5273     * caller.
5274     *
5275     * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, the Intent
5276     * you supply here can have {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
5277     * Intent.FLAG_GRANT_READ_URI_PERMISSION} and/or {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION
5278     * Intent.FLAG_GRANT_WRITE_URI_PERMISSION} set.  This will grant the
5279     * Activity receiving the result access to the specific URIs in the Intent.
5280     * Access will remain until the Activity has finished (it will remain across the hosting
5281     * process being killed and other temporary destruction) and will be added
5282     * to any existing set of URI permissions it already holds.
5283     *
5284     * @param resultCode The result code to propagate back to the originating
5285     *                   activity, often RESULT_CANCELED or RESULT_OK
5286     * @param data The data to propagate back to the originating activity.
5287     *
5288     * @see #RESULT_CANCELED
5289     * @see #RESULT_OK
5290     * @see #RESULT_FIRST_USER
5291     * @see #setResult(int)
5292     */
5293    public final void setResult(int resultCode, Intent data) {
5294        synchronized (this) {
5295            mResultCode = resultCode;
5296            mResultData = data;
5297        }
5298    }
5299
5300    /**
5301     * Return information about who launched this activity.  If the launching Intent
5302     * contains an {@link android.content.Intent#EXTRA_REFERRER Intent.EXTRA_REFERRER},
5303     * that will be returned as-is; otherwise, if known, an
5304     * {@link Intent#URI_ANDROID_APP_SCHEME android-app:} referrer URI containing the
5305     * package name that started the Intent will be returned.  This may return null if no
5306     * referrer can be identified -- it is neither explicitly specified, nor is it known which
5307     * application package was involved.
5308     *
5309     * <p>If called while inside the handling of {@link #onNewIntent}, this function will
5310     * return the referrer that submitted that new intent to the activity.  Otherwise, it
5311     * always returns the referrer of the original Intent.</p>
5312     *
5313     * <p>Note that this is <em>not</em> a security feature -- you can not trust the
5314     * referrer information, applications can spoof it.</p>
5315     */
5316    @Nullable
5317    public Uri getReferrer() {
5318        Intent intent = getIntent();
5319        try {
5320            Uri referrer = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
5321            if (referrer != null) {
5322                return referrer;
5323            }
5324            String referrerName = intent.getStringExtra(Intent.EXTRA_REFERRER_NAME);
5325            if (referrerName != null) {
5326                return Uri.parse(referrerName);
5327            }
5328        } catch (BadParcelableException e) {
5329            Log.w(TAG, "Cannot read referrer from intent;"
5330                    + " intent extras contain unknown custom Parcelable objects");
5331        }
5332        if (mReferrer != null) {
5333            return new Uri.Builder().scheme("android-app").authority(mReferrer).build();
5334        }
5335        return null;
5336    }
5337
5338    /**
5339     * Override to generate the desired referrer for the content currently being shown
5340     * by the app.  The default implementation returns null, meaning the referrer will simply
5341     * be the android-app: of the package name of this activity.  Return a non-null Uri to
5342     * have that supplied as the {@link Intent#EXTRA_REFERRER} of any activities started from it.
5343     */
5344    public Uri onProvideReferrer() {
5345        return null;
5346    }
5347
5348    /**
5349     * Return the name of the package that invoked this activity.  This is who
5350     * the data in {@link #setResult setResult()} will be sent to.  You can
5351     * use this information to validate that the recipient is allowed to
5352     * receive the data.
5353     *
5354     * <p class="note">Note: if the calling activity is not expecting a result (that is it
5355     * did not use the {@link #startActivityForResult}
5356     * form that includes a request code), then the calling package will be
5357     * null.</p>
5358     *
5359     * <p class="note">Note: prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
5360     * the result from this method was unstable.  If the process hosting the calling
5361     * package was no longer running, it would return null instead of the proper package
5362     * name.  You can use {@link #getCallingActivity()} and retrieve the package name
5363     * from that instead.</p>
5364     *
5365     * @return The package of the activity that will receive your
5366     *         reply, or null if none.
5367     */
5368    @Nullable
5369    public String getCallingPackage() {
5370        try {
5371            return ActivityManager.getService().getCallingPackage(mToken);
5372        } catch (RemoteException e) {
5373            return null;
5374        }
5375    }
5376
5377    /**
5378     * Return the name of the activity that invoked this activity.  This is
5379     * who the data in {@link #setResult setResult()} will be sent to.  You
5380     * can use this information to validate that the recipient is allowed to
5381     * receive the data.
5382     *
5383     * <p class="note">Note: if the calling activity is not expecting a result (that is it
5384     * did not use the {@link #startActivityForResult}
5385     * form that includes a request code), then the calling package will be
5386     * null.
5387     *
5388     * @return The ComponentName of the activity that will receive your
5389     *         reply, or null if none.
5390     */
5391    @Nullable
5392    public ComponentName getCallingActivity() {
5393        try {
5394            return ActivityManager.getService().getCallingActivity(mToken);
5395        } catch (RemoteException e) {
5396            return null;
5397        }
5398    }
5399
5400    /**
5401     * Control whether this activity's main window is visible.  This is intended
5402     * only for the special case of an activity that is not going to show a
5403     * UI itself, but can't just finish prior to onResume() because it needs
5404     * to wait for a service binding or such.  Setting this to false allows
5405     * you to prevent your UI from being shown during that time.
5406     *
5407     * <p>The default value for this is taken from the
5408     * {@link android.R.attr#windowNoDisplay} attribute of the activity's theme.
5409     */
5410    public void setVisible(boolean visible) {
5411        if (mVisibleFromClient != visible) {
5412            mVisibleFromClient = visible;
5413            if (mVisibleFromServer) {
5414                if (visible) makeVisible();
5415                else mDecor.setVisibility(View.INVISIBLE);
5416            }
5417        }
5418    }
5419
5420    void makeVisible() {
5421        if (!mWindowAdded) {
5422            ViewManager wm = getWindowManager();
5423            wm.addView(mDecor, getWindow().getAttributes());
5424            mWindowAdded = true;
5425        }
5426        mDecor.setVisibility(View.VISIBLE);
5427    }
5428
5429    /**
5430     * Check to see whether this activity is in the process of finishing,
5431     * either because you called {@link #finish} on it or someone else
5432     * has requested that it finished.  This is often used in
5433     * {@link #onPause} to determine whether the activity is simply pausing or
5434     * completely finishing.
5435     *
5436     * @return If the activity is finishing, returns true; else returns false.
5437     *
5438     * @see #finish
5439     */
5440    public boolean isFinishing() {
5441        return mFinished;
5442    }
5443
5444    /**
5445     * Returns true if the final {@link #onDestroy()} call has been made
5446     * on the Activity, so this instance is now dead.
5447     */
5448    public boolean isDestroyed() {
5449        return mDestroyed;
5450    }
5451
5452    /**
5453     * Check to see whether this activity is in the process of being destroyed in order to be
5454     * recreated with a new configuration. This is often used in
5455     * {@link #onStop} to determine whether the state needs to be cleaned up or will be passed
5456     * on to the next instance of the activity via {@link #onRetainNonConfigurationInstance()}.
5457     *
5458     * @return If the activity is being torn down in order to be recreated with a new configuration,
5459     * returns true; else returns false.
5460     */
5461    public boolean isChangingConfigurations() {
5462        return mChangingConfigurations;
5463    }
5464
5465    /**
5466     * Cause this Activity to be recreated with a new instance.  This results
5467     * in essentially the same flow as when the Activity is created due to
5468     * a configuration change -- the current instance will go through its
5469     * lifecycle to {@link #onDestroy} and a new instance then created after it.
5470     */
5471    public void recreate() {
5472        if (mParent != null) {
5473            throw new IllegalStateException("Can only be called on top-level activity");
5474        }
5475        if (Looper.myLooper() != mMainThread.getLooper()) {
5476            throw new IllegalStateException("Must be called from main thread");
5477        }
5478        try {
5479            ActivityManager.getService().requestActivityRelaunch(mToken);
5480        } catch (RemoteException e) {
5481        }
5482    }
5483
5484    /**
5485     * Finishes the current activity and specifies whether to remove the task associated with this
5486     * activity.
5487     */
5488    private void finish(int finishTask) {
5489        if (mParent == null) {
5490            int resultCode;
5491            Intent resultData;
5492            synchronized (this) {
5493                resultCode = mResultCode;
5494                resultData = mResultData;
5495            }
5496            if (false) Log.v(TAG, "Finishing self: token=" + mToken);
5497            try {
5498                if (resultData != null) {
5499                    resultData.prepareToLeaveProcess(this);
5500                }
5501                if (ActivityManager.getService()
5502                        .finishActivity(mToken, resultCode, resultData, finishTask)) {
5503                    mFinished = true;
5504                }
5505            } catch (RemoteException e) {
5506                // Empty
5507            }
5508        } else {
5509            mParent.finishFromChild(this);
5510        }
5511    }
5512
5513    /**
5514     * Call this when your activity is done and should be closed.  The
5515     * ActivityResult is propagated back to whoever launched you via
5516     * onActivityResult().
5517     */
5518    public void finish() {
5519        finish(DONT_FINISH_TASK_WITH_ACTIVITY);
5520    }
5521
5522    /**
5523     * Finish this activity as well as all activities immediately below it
5524     * in the current task that have the same affinity.  This is typically
5525     * used when an application can be launched on to another task (such as
5526     * from an ACTION_VIEW of a content type it understands) and the user
5527     * has used the up navigation to switch out of the current task and in
5528     * to its own task.  In this case, if the user has navigated down into
5529     * any other activities of the second application, all of those should
5530     * be removed from the original task as part of the task switch.
5531     *
5532     * <p>Note that this finish does <em>not</em> allow you to deliver results
5533     * to the previous activity, and an exception will be thrown if you are trying
5534     * to do so.</p>
5535     */
5536    public void finishAffinity() {
5537        if (mParent != null) {
5538            throw new IllegalStateException("Can not be called from an embedded activity");
5539        }
5540        if (mResultCode != RESULT_CANCELED || mResultData != null) {
5541            throw new IllegalStateException("Can not be called to deliver a result");
5542        }
5543        try {
5544            if (ActivityManager.getService().finishActivityAffinity(mToken)) {
5545                mFinished = true;
5546            }
5547        } catch (RemoteException e) {
5548            // Empty
5549        }
5550    }
5551
5552    /**
5553     * This is called when a child activity of this one calls its
5554     * {@link #finish} method.  The default implementation simply calls
5555     * finish() on this activity (the parent), finishing the entire group.
5556     *
5557     * @param child The activity making the call.
5558     *
5559     * @see #finish
5560     */
5561    public void finishFromChild(Activity child) {
5562        finish();
5563    }
5564
5565    /**
5566     * Reverses the Activity Scene entry Transition and triggers the calling Activity
5567     * to reverse its exit Transition. When the exit Transition completes,
5568     * {@link #finish()} is called. If no entry Transition was used, finish() is called
5569     * immediately and the Activity exit Transition is run.
5570     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, android.util.Pair[])
5571     */
5572    public void finishAfterTransition() {
5573        if (!mActivityTransitionState.startExitBackTransition(this)) {
5574            finish();
5575        }
5576    }
5577
5578    /**
5579     * Force finish another activity that you had previously started with
5580     * {@link #startActivityForResult}.
5581     *
5582     * @param requestCode The request code of the activity that you had
5583     *                    given to startActivityForResult().  If there are multiple
5584     *                    activities started with this request code, they
5585     *                    will all be finished.
5586     */
5587    public void finishActivity(int requestCode) {
5588        if (mParent == null) {
5589            try {
5590                ActivityManager.getService()
5591                    .finishSubActivity(mToken, mEmbeddedID, requestCode);
5592            } catch (RemoteException e) {
5593                // Empty
5594            }
5595        } else {
5596            mParent.finishActivityFromChild(this, requestCode);
5597        }
5598    }
5599
5600    /**
5601     * This is called when a child activity of this one calls its
5602     * finishActivity().
5603     *
5604     * @param child The activity making the call.
5605     * @param requestCode Request code that had been used to start the
5606     *                    activity.
5607     */
5608    public void finishActivityFromChild(@NonNull Activity child, int requestCode) {
5609        try {
5610            ActivityManager.getService()
5611                .finishSubActivity(mToken, child.mEmbeddedID, requestCode);
5612        } catch (RemoteException e) {
5613            // Empty
5614        }
5615    }
5616
5617    /**
5618     * Call this when your activity is done and should be closed and the task should be completely
5619     * removed as a part of finishing the root activity of the task.
5620     */
5621    public void finishAndRemoveTask() {
5622        finish(FINISH_TASK_WITH_ROOT_ACTIVITY);
5623    }
5624
5625    /**
5626     * Ask that the local app instance of this activity be released to free up its memory.
5627     * This is asking for the activity to be destroyed, but does <b>not</b> finish the activity --
5628     * a new instance of the activity will later be re-created if needed due to the user
5629     * navigating back to it.
5630     *
5631     * @return Returns true if the activity was in a state that it has started the process
5632     * of destroying its current instance; returns false if for any reason this could not
5633     * be done: it is currently visible to the user, it is already being destroyed, it is
5634     * being finished, it hasn't yet saved its state, etc.
5635     */
5636    public boolean releaseInstance() {
5637        try {
5638            return ActivityManager.getService().releaseActivityInstance(mToken);
5639        } catch (RemoteException e) {
5640            // Empty
5641        }
5642        return false;
5643    }
5644
5645    /**
5646     * Called when an activity you launched exits, giving you the requestCode
5647     * you started it with, the resultCode it returned, and any additional
5648     * data from it.  The <var>resultCode</var> will be
5649     * {@link #RESULT_CANCELED} if the activity explicitly returned that,
5650     * didn't return any result, or crashed during its operation.
5651     *
5652     * <p>You will receive this call immediately before onResume() when your
5653     * activity is re-starting.
5654     *
5655     * <p>This method is never invoked if your activity sets
5656     * {@link android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
5657     * <code>true</code>.
5658     *
5659     * @param requestCode The integer request code originally supplied to
5660     *                    startActivityForResult(), allowing you to identify who this
5661     *                    result came from.
5662     * @param resultCode The integer result code returned by the child activity
5663     *                   through its setResult().
5664     * @param data An Intent, which can return result data to the caller
5665     *               (various data can be attached to Intent "extras").
5666     *
5667     * @see #startActivityForResult
5668     * @see #createPendingResult
5669     * @see #setResult(int)
5670     */
5671    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
5672    }
5673
5674    /**
5675     * Called when an activity you launched with an activity transition exposes this
5676     * Activity through a returning activity transition, giving you the resultCode
5677     * and any additional data from it. This method will only be called if the activity
5678     * set a result code other than {@link #RESULT_CANCELED} and it supports activity
5679     * transitions with {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
5680     *
5681     * <p>The purpose of this function is to let the called Activity send a hint about
5682     * its state so that this underlying Activity can prepare to be exposed. A call to
5683     * this method does not guarantee that the called Activity has or will be exiting soon.
5684     * It only indicates that it will expose this Activity's Window and it has
5685     * some data to pass to prepare it.</p>
5686     *
5687     * @param resultCode The integer result code returned by the child activity
5688     *                   through its setResult().
5689     * @param data An Intent, which can return result data to the caller
5690     *               (various data can be attached to Intent "extras").
5691     */
5692    public void onActivityReenter(int resultCode, Intent data) {
5693    }
5694
5695    /**
5696     * Create a new PendingIntent object which you can hand to others
5697     * for them to use to send result data back to your
5698     * {@link #onActivityResult} callback.  The created object will be either
5699     * one-shot (becoming invalid after a result is sent back) or multiple
5700     * (allowing any number of results to be sent through it).
5701     *
5702     * @param requestCode Private request code for the sender that will be
5703     * associated with the result data when it is returned.  The sender can not
5704     * modify this value, allowing you to identify incoming results.
5705     * @param data Default data to supply in the result, which may be modified
5706     * by the sender.
5707     * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT PendingIntent.FLAG_ONE_SHOT},
5708     * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE},
5709     * {@link PendingIntent#FLAG_CANCEL_CURRENT PendingIntent.FLAG_CANCEL_CURRENT},
5710     * {@link PendingIntent#FLAG_UPDATE_CURRENT PendingIntent.FLAG_UPDATE_CURRENT},
5711     * or any of the flags as supported by
5712     * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
5713     * of the intent that can be supplied when the actual send happens.
5714     *
5715     * @return Returns an existing or new PendingIntent matching the given
5716     * parameters.  May return null only if
5717     * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE} has been
5718     * supplied.
5719     *
5720     * @see PendingIntent
5721     */
5722    public PendingIntent createPendingResult(int requestCode, @NonNull Intent data,
5723            @PendingIntent.Flags int flags) {
5724        String packageName = getPackageName();
5725        try {
5726            data.prepareToLeaveProcess(this);
5727            IIntentSender target =
5728                ActivityManager.getService().getIntentSender(
5729                        ActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName,
5730                        mParent == null ? mToken : mParent.mToken,
5731                        mEmbeddedID, requestCode, new Intent[] { data }, null, flags, null,
5732                        UserHandle.myUserId());
5733            return target != null ? new PendingIntent(target) : null;
5734        } catch (RemoteException e) {
5735            // Empty
5736        }
5737        return null;
5738    }
5739
5740    /**
5741     * Change the desired orientation of this activity.  If the activity
5742     * is currently in the foreground or otherwise impacting the screen
5743     * orientation, the screen will immediately be changed (possibly causing
5744     * the activity to be restarted). Otherwise, this will be used the next
5745     * time the activity is visible.
5746     *
5747     * @param requestedOrientation An orientation constant as used in
5748     * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
5749     */
5750    public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
5751        if (mParent == null) {
5752            try {
5753                ActivityManager.getService().setRequestedOrientation(
5754                        mToken, requestedOrientation);
5755            } catch (RemoteException e) {
5756                // Empty
5757            }
5758        } else {
5759            mParent.setRequestedOrientation(requestedOrientation);
5760        }
5761    }
5762
5763    /**
5764     * Return the current requested orientation of the activity.  This will
5765     * either be the orientation requested in its component's manifest, or
5766     * the last requested orientation given to
5767     * {@link #setRequestedOrientation(int)}.
5768     *
5769     * @return Returns an orientation constant as used in
5770     * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
5771     */
5772    @ActivityInfo.ScreenOrientation
5773    public int getRequestedOrientation() {
5774        if (mParent == null) {
5775            try {
5776                return ActivityManager.getService()
5777                        .getRequestedOrientation(mToken);
5778            } catch (RemoteException e) {
5779                // Empty
5780            }
5781        } else {
5782            return mParent.getRequestedOrientation();
5783        }
5784        return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5785    }
5786
5787    /**
5788     * Return the identifier of the task this activity is in.  This identifier
5789     * will remain the same for the lifetime of the activity.
5790     *
5791     * @return Task identifier, an opaque integer.
5792     */
5793    public int getTaskId() {
5794        try {
5795            return ActivityManager.getService()
5796                .getTaskForActivity(mToken, false);
5797        } catch (RemoteException e) {
5798            return -1;
5799        }
5800    }
5801
5802    /**
5803     * Return whether this activity is the root of a task.  The root is the
5804     * first activity in a task.
5805     *
5806     * @return True if this is the root activity, else false.
5807     */
5808    public boolean isTaskRoot() {
5809        try {
5810            return ActivityManager.getService().getTaskForActivity(mToken, true) >= 0;
5811        } catch (RemoteException e) {
5812            return false;
5813        }
5814    }
5815
5816    /**
5817     * Move the task containing this activity to the back of the activity
5818     * stack.  The activity's order within the task is unchanged.
5819     *
5820     * @param nonRoot If false then this only works if the activity is the root
5821     *                of a task; if true it will work for any activity in
5822     *                a task.
5823     *
5824     * @return If the task was moved (or it was already at the
5825     *         back) true is returned, else false.
5826     */
5827    public boolean moveTaskToBack(boolean nonRoot) {
5828        try {
5829            return ActivityManager.getService().moveActivityTaskToBack(
5830                    mToken, nonRoot);
5831        } catch (RemoteException e) {
5832            // Empty
5833        }
5834        return false;
5835    }
5836
5837    /**
5838     * Returns class name for this activity with the package prefix removed.
5839     * This is the default name used to read and write settings.
5840     *
5841     * @return The local class name.
5842     */
5843    @NonNull
5844    public String getLocalClassName() {
5845        final String pkg = getPackageName();
5846        final String cls = mComponent.getClassName();
5847        int packageLen = pkg.length();
5848        if (!cls.startsWith(pkg) || cls.length() <= packageLen
5849                || cls.charAt(packageLen) != '.') {
5850            return cls;
5851        }
5852        return cls.substring(packageLen+1);
5853    }
5854
5855    /**
5856     * Returns complete component name of this activity.
5857     *
5858     * @return Returns the complete component name for this activity
5859     */
5860    public ComponentName getComponentName()
5861    {
5862        return mComponent;
5863    }
5864
5865    /**
5866     * Retrieve a {@link SharedPreferences} object for accessing preferences
5867     * that are private to this activity.  This simply calls the underlying
5868     * {@link #getSharedPreferences(String, int)} method by passing in this activity's
5869     * class name as the preferences name.
5870     *
5871     * @param mode Operating mode.  Use {@link #MODE_PRIVATE} for the default
5872     *             operation.
5873     *
5874     * @return Returns the single SharedPreferences instance that can be used
5875     *         to retrieve and modify the preference values.
5876     */
5877    public SharedPreferences getPreferences(@Context.PreferencesMode int mode) {
5878        return getSharedPreferences(getLocalClassName(), mode);
5879    }
5880
5881    private void ensureSearchManager() {
5882        if (mSearchManager != null) {
5883            return;
5884        }
5885
5886        try {
5887            mSearchManager = new SearchManager(this, null);
5888        } catch (ServiceNotFoundException e) {
5889            throw new IllegalStateException(e);
5890        }
5891    }
5892
5893    @Override
5894    public Object getSystemService(@ServiceName @NonNull String name) {
5895        if (getBaseContext() == null) {
5896            throw new IllegalStateException(
5897                    "System services not available to Activities before onCreate()");
5898        }
5899
5900        if (WINDOW_SERVICE.equals(name)) {
5901            return mWindowManager;
5902        } else if (SEARCH_SERVICE.equals(name)) {
5903            ensureSearchManager();
5904            return mSearchManager;
5905        }
5906        return super.getSystemService(name);
5907    }
5908
5909    /**
5910     * Change the title associated with this activity.  If this is a
5911     * top-level activity, the title for its window will change.  If it
5912     * is an embedded activity, the parent can do whatever it wants
5913     * with it.
5914     */
5915    public void setTitle(CharSequence title) {
5916        mTitle = title;
5917        onTitleChanged(title, mTitleColor);
5918
5919        if (mParent != null) {
5920            mParent.onChildTitleChanged(this, title);
5921        }
5922    }
5923
5924    /**
5925     * Change the title associated with this activity.  If this is a
5926     * top-level activity, the title for its window will change.  If it
5927     * is an embedded activity, the parent can do whatever it wants
5928     * with it.
5929     */
5930    public void setTitle(int titleId) {
5931        setTitle(getText(titleId));
5932    }
5933
5934    /**
5935     * Change the color of the title associated with this activity.
5936     * <p>
5937     * This method is deprecated starting in API Level 11 and replaced by action
5938     * bar styles. For information on styling the Action Bar, read the <a
5939     * href="{@docRoot} guide/topics/ui/actionbar.html">Action Bar</a> developer
5940     * guide.
5941     *
5942     * @deprecated Use action bar styles instead.
5943     */
5944    @Deprecated
5945    public void setTitleColor(int textColor) {
5946        mTitleColor = textColor;
5947        onTitleChanged(mTitle, textColor);
5948    }
5949
5950    public final CharSequence getTitle() {
5951        return mTitle;
5952    }
5953
5954    public final int getTitleColor() {
5955        return mTitleColor;
5956    }
5957
5958    protected void onTitleChanged(CharSequence title, int color) {
5959        if (mTitleReady) {
5960            final Window win = getWindow();
5961            if (win != null) {
5962                win.setTitle(title);
5963                if (color != 0) {
5964                    win.setTitleColor(color);
5965                }
5966            }
5967            if (mActionBar != null) {
5968                mActionBar.setWindowTitle(title);
5969            }
5970        }
5971    }
5972
5973    protected void onChildTitleChanged(Activity childActivity, CharSequence title) {
5974    }
5975
5976    /**
5977     * Sets information describing the task with this activity for presentation inside the Recents
5978     * System UI. When {@link ActivityManager#getRecentTasks} is called, the activities of each task
5979     * are traversed in order from the topmost activity to the bottommost. The traversal continues
5980     * for each property until a suitable value is found. For each task the taskDescription will be
5981     * returned in {@link android.app.ActivityManager.TaskDescription}.
5982     *
5983     * @see ActivityManager#getRecentTasks
5984     * @see android.app.ActivityManager.TaskDescription
5985     *
5986     * @param taskDescription The TaskDescription properties that describe the task with this activity
5987     */
5988    public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
5989        if (mTaskDescription != taskDescription) {
5990            mTaskDescription.copyFromPreserveHiddenFields(taskDescription);
5991            // Scale the icon down to something reasonable if it is provided
5992            if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) {
5993                final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
5994                final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size,
5995                        true);
5996                mTaskDescription.setIcon(icon);
5997            }
5998        }
5999        try {
6000            ActivityManager.getService().setTaskDescription(mToken, mTaskDescription);
6001        } catch (RemoteException e) {
6002        }
6003    }
6004
6005    /**
6006     * Sets the visibility of the progress bar in the title.
6007     * <p>
6008     * In order for the progress bar to be shown, the feature must be requested
6009     * via {@link #requestWindowFeature(int)}.
6010     *
6011     * @param visible Whether to show the progress bars in the title.
6012     * @deprecated No longer supported starting in API 21.
6013     */
6014    @Deprecated
6015    public final void setProgressBarVisibility(boolean visible) {
6016        getWindow().setFeatureInt(Window.FEATURE_PROGRESS, visible ? Window.PROGRESS_VISIBILITY_ON :
6017            Window.PROGRESS_VISIBILITY_OFF);
6018    }
6019
6020    /**
6021     * Sets the visibility of the indeterminate progress bar in the title.
6022     * <p>
6023     * In order for the progress bar to be shown, the feature must be requested
6024     * via {@link #requestWindowFeature(int)}.
6025     *
6026     * @param visible Whether to show the progress bars in the title.
6027     * @deprecated No longer supported starting in API 21.
6028     */
6029    @Deprecated
6030    public final void setProgressBarIndeterminateVisibility(boolean visible) {
6031        getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
6032                visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF);
6033    }
6034
6035    /**
6036     * Sets whether the horizontal progress bar in the title should be indeterminate (the circular
6037     * is always indeterminate).
6038     * <p>
6039     * In order for the progress bar to be shown, the feature must be requested
6040     * via {@link #requestWindowFeature(int)}.
6041     *
6042     * @param indeterminate Whether the horizontal progress bar should be indeterminate.
6043     * @deprecated No longer supported starting in API 21.
6044     */
6045    @Deprecated
6046    public final void setProgressBarIndeterminate(boolean indeterminate) {
6047        getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
6048                indeterminate ? Window.PROGRESS_INDETERMINATE_ON
6049                        : Window.PROGRESS_INDETERMINATE_OFF);
6050    }
6051
6052    /**
6053     * Sets the progress for the progress bars in the title.
6054     * <p>
6055     * In order for the progress bar to be shown, the feature must be requested
6056     * via {@link #requestWindowFeature(int)}.
6057     *
6058     * @param progress The progress for the progress bar. Valid ranges are from
6059     *            0 to 10000 (both inclusive). If 10000 is given, the progress
6060     *            bar will be completely filled and will fade out.
6061     * @deprecated No longer supported starting in API 21.
6062     */
6063    @Deprecated
6064    public final void setProgress(int progress) {
6065        getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START);
6066    }
6067
6068    /**
6069     * Sets the secondary progress for the progress bar in the title. This
6070     * progress is drawn between the primary progress (set via
6071     * {@link #setProgress(int)} and the background. It can be ideal for media
6072     * scenarios such as showing the buffering progress while the default
6073     * progress shows the play progress.
6074     * <p>
6075     * In order for the progress bar to be shown, the feature must be requested
6076     * via {@link #requestWindowFeature(int)}.
6077     *
6078     * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from
6079     *            0 to 10000 (both inclusive).
6080     * @deprecated No longer supported starting in API 21.
6081     */
6082    @Deprecated
6083    public final void setSecondaryProgress(int secondaryProgress) {
6084        getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
6085                secondaryProgress + Window.PROGRESS_SECONDARY_START);
6086    }
6087
6088    /**
6089     * Suggests an audio stream whose volume should be changed by the hardware
6090     * volume controls.
6091     * <p>
6092     * The suggested audio stream will be tied to the window of this Activity.
6093     * Volume requests which are received while the Activity is in the
6094     * foreground will affect this stream.
6095     * <p>
6096     * It is not guaranteed that the hardware volume controls will always change
6097     * this stream's volume (for example, if a call is in progress, its stream's
6098     * volume may be changed instead). To reset back to the default, use
6099     * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}.
6100     *
6101     * @param streamType The type of the audio stream whose volume should be
6102     *            changed by the hardware volume controls.
6103     */
6104    public final void setVolumeControlStream(int streamType) {
6105        getWindow().setVolumeControlStream(streamType);
6106    }
6107
6108    /**
6109     * Gets the suggested audio stream whose volume should be changed by the
6110     * hardware volume controls.
6111     *
6112     * @return The suggested audio stream type whose volume should be changed by
6113     *         the hardware volume controls.
6114     * @see #setVolumeControlStream(int)
6115     */
6116    public final int getVolumeControlStream() {
6117        return getWindow().getVolumeControlStream();
6118    }
6119
6120    /**
6121     * Sets a {@link MediaController} to send media keys and volume changes to.
6122     * <p>
6123     * The controller will be tied to the window of this Activity. Media key and
6124     * volume events which are received while the Activity is in the foreground
6125     * will be forwarded to the controller and used to invoke transport controls
6126     * or adjust the volume. This may be used instead of or in addition to
6127     * {@link #setVolumeControlStream} to affect a specific session instead of a
6128     * specific stream.
6129     * <p>
6130     * It is not guaranteed that the hardware volume controls will always change
6131     * this session's volume (for example, if a call is in progress, its
6132     * stream's volume may be changed instead). To reset back to the default use
6133     * null as the controller.
6134     *
6135     * @param controller The controller for the session which should receive
6136     *            media keys and volume changes.
6137     */
6138    public final void setMediaController(MediaController controller) {
6139        getWindow().setMediaController(controller);
6140    }
6141
6142    /**
6143     * Gets the controller which should be receiving media key and volume events
6144     * while this activity is in the foreground.
6145     *
6146     * @return The controller which should receive events.
6147     * @see #setMediaController(android.media.session.MediaController)
6148     */
6149    public final MediaController getMediaController() {
6150        return getWindow().getMediaController();
6151    }
6152
6153    /**
6154     * Runs the specified action on the UI thread. If the current thread is the UI
6155     * thread, then the action is executed immediately. If the current thread is
6156     * not the UI thread, the action is posted to the event queue of the UI thread.
6157     *
6158     * @param action the action to run on the UI thread
6159     */
6160    public final void runOnUiThread(Runnable action) {
6161        if (Thread.currentThread() != mUiThread) {
6162            mHandler.post(action);
6163        } else {
6164            action.run();
6165        }
6166    }
6167
6168    /**
6169     * Standard implementation of
6170     * {@link android.view.LayoutInflater.Factory#onCreateView} used when
6171     * inflating with the LayoutInflater returned by {@link #getSystemService}.
6172     * This implementation does nothing and is for
6173     * pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} apps.  Newer apps
6174     * should use {@link #onCreateView(View, String, Context, AttributeSet)}.
6175     *
6176     * @see android.view.LayoutInflater#createView
6177     * @see android.view.Window#getLayoutInflater
6178     */
6179    @Nullable
6180    public View onCreateView(String name, Context context, AttributeSet attrs) {
6181        return null;
6182    }
6183
6184    /**
6185     * Standard implementation of
6186     * {@link android.view.LayoutInflater.Factory2#onCreateView(View, String, Context, AttributeSet)}
6187     * used when inflating with the LayoutInflater returned by {@link #getSystemService}.
6188     * This implementation handles <fragment> tags to embed fragments inside
6189     * of the activity.
6190     *
6191     * @see android.view.LayoutInflater#createView
6192     * @see android.view.Window#getLayoutInflater
6193     */
6194    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
6195        if (!"fragment".equals(name)) {
6196            return onCreateView(name, context, attrs);
6197        }
6198
6199        return mFragments.onCreateView(parent, name, context, attrs);
6200    }
6201
6202    /**
6203     * Print the Activity's state into the given stream.  This gets invoked if
6204     * you run "adb shell dumpsys activity &lt;activity_component_name&gt;".
6205     *
6206     * @param prefix Desired prefix to prepend at each line of output.
6207     * @param fd The raw file descriptor that the dump is being sent to.
6208     * @param writer The PrintWriter to which you should dump your state.  This will be
6209     * closed for you after you return.
6210     * @param args additional arguments to the dump request.
6211     */
6212    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
6213        dumpInner(prefix, fd, writer, args);
6214    }
6215
6216    void dumpInner(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
6217        writer.print(prefix); writer.print("Local Activity ");
6218                writer.print(Integer.toHexString(System.identityHashCode(this)));
6219                writer.println(" State:");
6220        String innerPrefix = prefix + "  ";
6221        writer.print(innerPrefix); writer.print("mResumed=");
6222                writer.print(mResumed); writer.print(" mStopped=");
6223                writer.print(mStopped); writer.print(" mFinished=");
6224                writer.println(mFinished);
6225        writer.print(innerPrefix); writer.print("mChangingConfigurations=");
6226                writer.println(mChangingConfigurations);
6227        writer.print(innerPrefix); writer.print("mCurrentConfig=");
6228                writer.println(mCurrentConfig);
6229
6230        mFragments.dumpLoaders(innerPrefix, fd, writer, args);
6231        mFragments.getFragmentManager().dump(innerPrefix, fd, writer, args);
6232        if (mVoiceInteractor != null) {
6233            mVoiceInteractor.dump(innerPrefix, fd, writer, args);
6234        }
6235
6236        if (getWindow() != null &&
6237                getWindow().peekDecorView() != null &&
6238                getWindow().peekDecorView().getViewRootImpl() != null) {
6239            getWindow().peekDecorView().getViewRootImpl().dump(prefix, fd, writer, args);
6240        }
6241
6242        mHandler.getLooper().dump(new PrintWriterPrinter(writer), prefix);
6243    }
6244
6245    /**
6246     * Bit indicating that this activity is "immersive" and should not be
6247     * interrupted by notifications if possible.
6248     *
6249     * This value is initially set by the manifest property
6250     * <code>android:immersive</code> but may be changed at runtime by
6251     * {@link #setImmersive}.
6252     *
6253     * @see #setImmersive(boolean)
6254     * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE
6255     */
6256    public boolean isImmersive() {
6257        try {
6258            return ActivityManager.getService().isImmersive(mToken);
6259        } catch (RemoteException e) {
6260            return false;
6261        }
6262    }
6263
6264    /**
6265     * Indication of whether this is the highest level activity in this task. Can be used to
6266     * determine whether an activity launched by this activity was placed in the same task or
6267     * another task.
6268     *
6269     * @return true if this is the topmost, non-finishing activity in its task.
6270     */
6271    private boolean isTopOfTask() {
6272        if (mToken == null || mWindow == null) {
6273            return false;
6274        }
6275        try {
6276            return ActivityManager.getService().isTopOfTask(getActivityToken());
6277        } catch (RemoteException e) {
6278            return false;
6279        }
6280    }
6281
6282    /**
6283     * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} to a
6284     * fullscreen opaque Activity.
6285     * <p>
6286     * Call this whenever the background of a translucent Activity has changed to become opaque.
6287     * Doing so will allow the {@link android.view.Surface} of the Activity behind to be released.
6288     * <p>
6289     * This call has no effect on non-translucent activities or on activities with the
6290     * {@link android.R.attr#windowIsFloating} attribute.
6291     *
6292     * @see #convertToTranslucent(android.app.Activity.TranslucentConversionListener,
6293     * ActivityOptions)
6294     * @see TranslucentConversionListener
6295     *
6296     * @hide
6297     */
6298    @SystemApi
6299    public void convertFromTranslucent() {
6300        try {
6301            mTranslucentCallback = null;
6302            if (ActivityManager.getService().convertFromTranslucent(mToken)) {
6303                WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true);
6304            }
6305        } catch (RemoteException e) {
6306            // pass
6307        }
6308    }
6309
6310    /**
6311     * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} back from
6312     * opaque to translucent following a call to {@link #convertFromTranslucent()}.
6313     * <p>
6314     * Calling this allows the Activity behind this one to be seen again. Once all such Activities
6315     * have been redrawn {@link TranslucentConversionListener#onTranslucentConversionComplete} will
6316     * be called indicating that it is safe to make this activity translucent again. Until
6317     * {@link TranslucentConversionListener#onTranslucentConversionComplete} is called the image
6318     * behind the frontmost Activity will be indeterminate.
6319     * <p>
6320     * This call has no effect on non-translucent activities or on activities with the
6321     * {@link android.R.attr#windowIsFloating} attribute.
6322     *
6323     * @param callback the method to call when all visible Activities behind this one have been
6324     * drawn and it is safe to make this Activity translucent again.
6325     * @param options activity options delivered to the activity below this one. The options
6326     * are retrieved using {@link #getActivityOptions}.
6327     * @return <code>true</code> if Window was opaque and will become translucent or
6328     * <code>false</code> if window was translucent and no change needed to be made.
6329     *
6330     * @see #convertFromTranslucent()
6331     * @see TranslucentConversionListener
6332     *
6333     * @hide
6334     */
6335    @SystemApi
6336    public boolean convertToTranslucent(TranslucentConversionListener callback,
6337            ActivityOptions options) {
6338        boolean drawComplete;
6339        try {
6340            mTranslucentCallback = callback;
6341            mChangeCanvasToTranslucent = ActivityManager.getService().convertToTranslucent(
6342                    mToken, options == null ? null : options.toBundle());
6343            WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
6344            drawComplete = true;
6345        } catch (RemoteException e) {
6346            // Make callback return as though it timed out.
6347            mChangeCanvasToTranslucent = false;
6348            drawComplete = false;
6349        }
6350        if (!mChangeCanvasToTranslucent && mTranslucentCallback != null) {
6351            // Window is already translucent.
6352            mTranslucentCallback.onTranslucentConversionComplete(drawComplete);
6353        }
6354        return mChangeCanvasToTranslucent;
6355    }
6356
6357    /** @hide */
6358    void onTranslucentConversionComplete(boolean drawComplete) {
6359        if (mTranslucentCallback != null) {
6360            mTranslucentCallback.onTranslucentConversionComplete(drawComplete);
6361            mTranslucentCallback = null;
6362        }
6363        if (mChangeCanvasToTranslucent) {
6364            WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
6365        }
6366    }
6367
6368    /** @hide */
6369    public void onNewActivityOptions(ActivityOptions options) {
6370        mActivityTransitionState.setEnterActivityOptions(this, options);
6371        if (!mStopped) {
6372            mActivityTransitionState.enterReady(this);
6373        }
6374    }
6375
6376    /**
6377     * Retrieve the ActivityOptions passed in from the launching activity or passed back
6378     * from an activity launched by this activity in its call to {@link
6379     * #convertToTranslucent(TranslucentConversionListener, ActivityOptions)}
6380     *
6381     * @return The ActivityOptions passed to {@link #convertToTranslucent}.
6382     * @hide
6383     */
6384    ActivityOptions getActivityOptions() {
6385        try {
6386            return ActivityOptions.fromBundle(
6387                    ActivityManager.getService().getActivityOptions(mToken));
6388        } catch (RemoteException e) {
6389        }
6390        return null;
6391    }
6392
6393    /**
6394     * Activities that want to remain visible behind a translucent activity above them must call
6395     * this method anytime between the start of {@link #onResume()} and the return from
6396     * {@link #onPause()}. If this call is successful then the activity will remain visible after
6397     * {@link #onPause()} is called, and is allowed to continue playing media in the background.
6398     *
6399     * <p>The actions of this call are reset each time that this activity is brought to the
6400     * front. That is, every time {@link #onResume()} is called the activity will be assumed
6401     * to not have requested visible behind. Therefore, if you want this activity to continue to
6402     * be visible in the background you must call this method again.
6403     *
6404     * <p>Only fullscreen opaque activities may make this call. I.e. this call is a nop
6405     * for dialog and translucent activities.
6406     *
6407     * <p>Under all circumstances, the activity must stop playing and release resources prior to or
6408     * within a call to {@link #onVisibleBehindCanceled()} or if this call returns false.
6409     *
6410     * <p>False will be returned any time this method is called between the return of onPause and
6411     *      the next call to onResume.
6412     *
6413     * @deprecated This method's functionality is no longer supported as of
6414     *             {@link android.os.Build.VERSION_CODES#O} and will be removed in a future release.
6415     *
6416     * @param visible true to notify the system that the activity wishes to be visible behind other
6417     *                translucent activities, false to indicate otherwise. Resources must be
6418     *                released when passing false to this method.
6419     *
6420     * @return the resulting visibiity state. If true the activity will remain visible beyond
6421     *      {@link #onPause()} if the next activity is translucent or not fullscreen. If false
6422     *      then the activity may not count on being visible behind other translucent activities,
6423     *      and must stop any media playback and release resources.
6424     *      Returning false may occur in lieu of a call to {@link #onVisibleBehindCanceled()} so
6425     *      the return value must be checked.
6426     *
6427     * @see #onVisibleBehindCanceled()
6428     */
6429    @Deprecated
6430    public boolean requestVisibleBehind(boolean visible) {
6431        if (!mResumed) {
6432            // Do not permit paused or stopped activities to do this.
6433            visible = false;
6434        }
6435        try {
6436            mVisibleBehind = ActivityManager.getService()
6437                    .requestVisibleBehind(mToken, visible) && visible;
6438        } catch (RemoteException e) {
6439            mVisibleBehind = false;
6440        }
6441        return mVisibleBehind;
6442    }
6443
6444    /**
6445     * Called when a translucent activity over this activity is becoming opaque or another
6446     * activity is being launched. Activities that override this method must call
6447     * <code>super.onVisibleBehindCanceled()</code> or a SuperNotCalledException will be thrown.
6448     *
6449     * <p>When this method is called the activity has 500 msec to release any resources it may be
6450     * using while visible in the background.
6451     * If the activity has not returned from this method in 500 msec the system will destroy
6452     * the activity and kill the process in order to recover the resources for another
6453     * process. Otherwise {@link #onStop()} will be called following return.
6454     *
6455     * @see #requestVisibleBehind(boolean)
6456     *
6457     * @deprecated This method's functionality is no longer supported as of
6458     * {@link android.os.Build.VERSION_CODES#O} and will be removed in a future release.
6459     */
6460    @Deprecated
6461    @CallSuper
6462    public void onVisibleBehindCanceled() {
6463        mCalled = true;
6464    }
6465
6466    /**
6467     * Translucent activities may call this to determine if there is an activity below them that
6468     * is currently set to be visible in the background.
6469     *
6470     * @deprecated This method's functionality is no longer supported as of
6471     * {@link android.os.Build.VERSION_CODES#O} and will be removed in a future release.
6472     *
6473     * @return true if an activity below is set to visible according to the most recent call to
6474     * {@link #requestVisibleBehind(boolean)}, false otherwise.
6475     *
6476     * @see #requestVisibleBehind(boolean)
6477     * @see #onVisibleBehindCanceled()
6478     * @see #onBackgroundVisibleBehindChanged(boolean)
6479     * @hide
6480     */
6481    @Deprecated
6482    @SystemApi
6483    public boolean isBackgroundVisibleBehind() {
6484        try {
6485            return ActivityManager.getService().isBackgroundVisibleBehind(mToken);
6486        } catch (RemoteException e) {
6487        }
6488        return false;
6489    }
6490
6491    /**
6492     * The topmost foreground activity will receive this call when the background visibility state
6493     * of the activity below it changes.
6494     *
6495     * This call may be a consequence of {@link #requestVisibleBehind(boolean)} or might be
6496     * due to a background activity finishing itself.
6497     *
6498     * @deprecated This method's functionality is no longer supported as of
6499     * {@link android.os.Build.VERSION_CODES#O} and will be removed in a future release.
6500     *
6501     * @param visible true if a background activity is visible, false otherwise.
6502     *
6503     * @see #requestVisibleBehind(boolean)
6504     * @see #onVisibleBehindCanceled()
6505     * @hide
6506     */
6507    @Deprecated
6508    @SystemApi
6509    public void onBackgroundVisibleBehindChanged(boolean visible) {
6510    }
6511
6512    /**
6513     * Activities cannot draw during the period that their windows are animating in. In order
6514     * to know when it is safe to begin drawing they can override this method which will be
6515     * called when the entering animation has completed.
6516     */
6517    public void onEnterAnimationComplete() {
6518    }
6519
6520    /**
6521     * @hide
6522     */
6523    public void dispatchEnterAnimationComplete() {
6524        onEnterAnimationComplete();
6525        if (getWindow() != null && getWindow().getDecorView() != null) {
6526            getWindow().getDecorView().getViewTreeObserver().dispatchOnEnterAnimationComplete();
6527        }
6528    }
6529
6530    /**
6531     * Adjust the current immersive mode setting.
6532     *
6533     * Note that changing this value will have no effect on the activity's
6534     * {@link android.content.pm.ActivityInfo} structure; that is, if
6535     * <code>android:immersive</code> is set to <code>true</code>
6536     * in the application's manifest entry for this activity, the {@link
6537     * android.content.pm.ActivityInfo#flags ActivityInfo.flags} member will
6538     * always have its {@link android.content.pm.ActivityInfo#FLAG_IMMERSIVE
6539     * FLAG_IMMERSIVE} bit set.
6540     *
6541     * @see #isImmersive()
6542     * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE
6543     */
6544    public void setImmersive(boolean i) {
6545        try {
6546            ActivityManager.getService().setImmersive(mToken, i);
6547        } catch (RemoteException e) {
6548            // pass
6549        }
6550    }
6551
6552    /**
6553     * Enable or disable virtual reality (VR) mode for this Activity.
6554     *
6555     * <p>VR mode is a hint to Android system to switch to a mode optimized for VR applications
6556     * while this Activity has user focus.</p>
6557     *
6558     * <p>It is recommended that applications additionally declare
6559     * {@link android.R.attr#enableVrMode} in their manifest to allow for smooth activity
6560     * transitions when switching between VR activities.</p>
6561     *
6562     * <p>If the requested {@link android.service.vr.VrListenerService} component is not available,
6563     * VR mode will not be started.  Developers can handle this case as follows:</p>
6564     *
6565     * <pre>
6566     * String servicePackage = "com.whatever.app";
6567     * String serviceClass = "com.whatever.app.MyVrListenerService";
6568     *
6569     * // Name of the component of the VrListenerService to start.
6570     * ComponentName serviceComponent = new ComponentName(servicePackage, serviceClass);
6571     *
6572     * try {
6573     *    setVrModeEnabled(true, myComponentName);
6574     * } catch (PackageManager.NameNotFoundException e) {
6575     *        List&lt;ApplicationInfo> installed = getPackageManager().getInstalledApplications(0);
6576     *        boolean isInstalled = false;
6577     *        for (ApplicationInfo app : installed) {
6578     *            if (app.packageName.equals(servicePackage)) {
6579     *                isInstalled = true;
6580     *                break;
6581     *            }
6582     *        }
6583     *        if (isInstalled) {
6584     *            // Package is installed, but not enabled in Settings.  Let user enable it.
6585     *            startActivity(new Intent(Settings.ACTION_VR_LISTENER_SETTINGS));
6586     *        } else {
6587     *            // Package is not installed.  Send an intent to download this.
6588     *            sentIntentToLaunchAppStore(servicePackage);
6589     *        }
6590     * }
6591     * </pre>
6592     *
6593     * @param enabled {@code true} to enable this mode.
6594     * @param requestedComponent the name of the component to use as a
6595     *        {@link android.service.vr.VrListenerService} while VR mode is enabled.
6596     *
6597     * @throws android.content.pm.PackageManager.NameNotFoundException if the given component
6598     *    to run as a {@link android.service.vr.VrListenerService} is not installed, or has
6599     *    not been enabled in user settings.
6600     *
6601     * @see android.content.pm.PackageManager#FEATURE_VR_MODE
6602     * @see android.content.pm.PackageManager#FEATURE_VR_MODE_HIGH_PERFORMANCE
6603     * @see android.service.vr.VrListenerService
6604     * @see android.provider.Settings#ACTION_VR_LISTENER_SETTINGS
6605     * @see android.R.attr#enableVrMode
6606     */
6607    public void setVrModeEnabled(boolean enabled, @NonNull ComponentName requestedComponent)
6608          throws PackageManager.NameNotFoundException {
6609        try {
6610            if (ActivityManager.getService().setVrMode(mToken, enabled, requestedComponent)
6611                    != 0) {
6612                throw new PackageManager.NameNotFoundException(
6613                        requestedComponent.flattenToString());
6614            }
6615        } catch (RemoteException e) {
6616            // pass
6617        }
6618    }
6619
6620    /**
6621     * Start an action mode of the default type {@link ActionMode#TYPE_PRIMARY}.
6622     *
6623     * @param callback Callback that will manage lifecycle events for this action mode
6624     * @return The ActionMode that was started, or null if it was canceled
6625     *
6626     * @see ActionMode
6627     */
6628    @Nullable
6629    public ActionMode startActionMode(ActionMode.Callback callback) {
6630        return mWindow.getDecorView().startActionMode(callback);
6631    }
6632
6633    /**
6634     * Start an action mode of the given type.
6635     *
6636     * @param callback Callback that will manage lifecycle events for this action mode
6637     * @param type One of {@link ActionMode#TYPE_PRIMARY} or {@link ActionMode#TYPE_FLOATING}.
6638     * @return The ActionMode that was started, or null if it was canceled
6639     *
6640     * @see ActionMode
6641     */
6642    @Nullable
6643    public ActionMode startActionMode(ActionMode.Callback callback, int type) {
6644        return mWindow.getDecorView().startActionMode(callback, type);
6645    }
6646
6647    /**
6648     * Give the Activity a chance to control the UI for an action mode requested
6649     * by the system.
6650     *
6651     * <p>Note: If you are looking for a notification callback that an action mode
6652     * has been started for this activity, see {@link #onActionModeStarted(ActionMode)}.</p>
6653     *
6654     * @param callback The callback that should control the new action mode
6655     * @return The new action mode, or <code>null</code> if the activity does not want to
6656     *         provide special handling for this action mode. (It will be handled by the system.)
6657     */
6658    @Nullable
6659    @Override
6660    public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
6661        // Only Primary ActionModes are represented in the ActionBar.
6662        if (mActionModeTypeStarting == ActionMode.TYPE_PRIMARY) {
6663            initWindowDecorActionBar();
6664            if (mActionBar != null) {
6665                return mActionBar.startActionMode(callback);
6666            }
6667        }
6668        return null;
6669    }
6670
6671    /**
6672     * {@inheritDoc}
6673     */
6674    @Nullable
6675    @Override
6676    public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
6677        try {
6678            mActionModeTypeStarting = type;
6679            return onWindowStartingActionMode(callback);
6680        } finally {
6681            mActionModeTypeStarting = ActionMode.TYPE_PRIMARY;
6682        }
6683    }
6684
6685    /**
6686     * Notifies the Activity that an action mode has been started.
6687     * Activity subclasses overriding this method should call the superclass implementation.
6688     *
6689     * @param mode The new action mode.
6690     */
6691    @CallSuper
6692    @Override
6693    public void onActionModeStarted(ActionMode mode) {
6694    }
6695
6696    /**
6697     * Notifies the activity that an action mode has finished.
6698     * Activity subclasses overriding this method should call the superclass implementation.
6699     *
6700     * @param mode The action mode that just finished.
6701     */
6702    @CallSuper
6703    @Override
6704    public void onActionModeFinished(ActionMode mode) {
6705    }
6706
6707    /**
6708     * Returns true if the app should recreate the task when navigating 'up' from this activity
6709     * by using targetIntent.
6710     *
6711     * <p>If this method returns false the app can trivially call
6712     * {@link #navigateUpTo(Intent)} using the same parameters to correctly perform
6713     * up navigation. If this method returns false, the app should synthesize a new task stack
6714     * by using {@link TaskStackBuilder} or another similar mechanism to perform up navigation.</p>
6715     *
6716     * @param targetIntent An intent representing the target destination for up navigation
6717     * @return true if navigating up should recreate a new task stack, false if the same task
6718     *         should be used for the destination
6719     */
6720    public boolean shouldUpRecreateTask(Intent targetIntent) {
6721        try {
6722            PackageManager pm = getPackageManager();
6723            ComponentName cn = targetIntent.getComponent();
6724            if (cn == null) {
6725                cn = targetIntent.resolveActivity(pm);
6726            }
6727            ActivityInfo info = pm.getActivityInfo(cn, 0);
6728            if (info.taskAffinity == null) {
6729                return false;
6730            }
6731            return ActivityManager.getService()
6732                    .shouldUpRecreateTask(mToken, info.taskAffinity);
6733        } catch (RemoteException e) {
6734            return false;
6735        } catch (NameNotFoundException e) {
6736            return false;
6737        }
6738    }
6739
6740    /**
6741     * Navigate from this activity to the activity specified by upIntent, finishing this activity
6742     * in the process. If the activity indicated by upIntent already exists in the task's history,
6743     * this activity and all others before the indicated activity in the history stack will be
6744     * finished.
6745     *
6746     * <p>If the indicated activity does not appear in the history stack, this will finish
6747     * each activity in this task until the root activity of the task is reached, resulting in
6748     * an "in-app home" behavior. This can be useful in apps with a complex navigation hierarchy
6749     * when an activity may be reached by a path not passing through a canonical parent
6750     * activity.</p>
6751     *
6752     * <p>This method should be used when performing up navigation from within the same task
6753     * as the destination. If up navigation should cross tasks in some cases, see
6754     * {@link #shouldUpRecreateTask(Intent)}.</p>
6755     *
6756     * @param upIntent An intent representing the target destination for up navigation
6757     *
6758     * @return true if up navigation successfully reached the activity indicated by upIntent and
6759     *         upIntent was delivered to it. false if an instance of the indicated activity could
6760     *         not be found and this activity was simply finished normally.
6761     */
6762    public boolean navigateUpTo(Intent upIntent) {
6763        if (mParent == null) {
6764            ComponentName destInfo = upIntent.getComponent();
6765            if (destInfo == null) {
6766                destInfo = upIntent.resolveActivity(getPackageManager());
6767                if (destInfo == null) {
6768                    return false;
6769                }
6770                upIntent = new Intent(upIntent);
6771                upIntent.setComponent(destInfo);
6772            }
6773            int resultCode;
6774            Intent resultData;
6775            synchronized (this) {
6776                resultCode = mResultCode;
6777                resultData = mResultData;
6778            }
6779            if (resultData != null) {
6780                resultData.prepareToLeaveProcess(this);
6781            }
6782            try {
6783                upIntent.prepareToLeaveProcess(this);
6784                return ActivityManager.getService().navigateUpTo(mToken, upIntent,
6785                        resultCode, resultData);
6786            } catch (RemoteException e) {
6787                return false;
6788            }
6789        } else {
6790            return mParent.navigateUpToFromChild(this, upIntent);
6791        }
6792    }
6793
6794    /**
6795     * This is called when a child activity of this one calls its
6796     * {@link #navigateUpTo} method.  The default implementation simply calls
6797     * navigateUpTo(upIntent) on this activity (the parent).
6798     *
6799     * @param child The activity making the call.
6800     * @param upIntent An intent representing the target destination for up navigation
6801     *
6802     * @return true if up navigation successfully reached the activity indicated by upIntent and
6803     *         upIntent was delivered to it. false if an instance of the indicated activity could
6804     *         not be found and this activity was simply finished normally.
6805     */
6806    public boolean navigateUpToFromChild(Activity child, Intent upIntent) {
6807        return navigateUpTo(upIntent);
6808    }
6809
6810    /**
6811     * Obtain an {@link Intent} that will launch an explicit target activity specified by
6812     * this activity's logical parent. The logical parent is named in the application's manifest
6813     * by the {@link android.R.attr#parentActivityName parentActivityName} attribute.
6814     * Activity subclasses may override this method to modify the Intent returned by
6815     * super.getParentActivityIntent() or to implement a different mechanism of retrieving
6816     * the parent intent entirely.
6817     *
6818     * @return a new Intent targeting the defined parent of this activity or null if
6819     *         there is no valid parent.
6820     */
6821    @Nullable
6822    public Intent getParentActivityIntent() {
6823        final String parentName = mActivityInfo.parentActivityName;
6824        if (TextUtils.isEmpty(parentName)) {
6825            return null;
6826        }
6827
6828        // If the parent itself has no parent, generate a main activity intent.
6829        final ComponentName target = new ComponentName(this, parentName);
6830        try {
6831            final ActivityInfo parentInfo = getPackageManager().getActivityInfo(target, 0);
6832            final String parentActivity = parentInfo.parentActivityName;
6833            final Intent parentIntent = parentActivity == null
6834                    ? Intent.makeMainActivity(target)
6835                    : new Intent().setComponent(target);
6836            return parentIntent;
6837        } catch (NameNotFoundException e) {
6838            Log.e(TAG, "getParentActivityIntent: bad parentActivityName '" + parentName +
6839                    "' in manifest");
6840            return null;
6841        }
6842    }
6843
6844    /**
6845     * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
6846     * android.view.View, String)} was used to start an Activity, <var>callback</var>
6847     * will be called to handle shared elements on the <i>launched</i> Activity. This requires
6848     * {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
6849     *
6850     * @param callback Used to manipulate shared element transitions on the launched Activity.
6851     */
6852    public void setEnterSharedElementCallback(SharedElementCallback callback) {
6853        if (callback == null) {
6854            callback = SharedElementCallback.NULL_CALLBACK;
6855        }
6856        mEnterTransitionListener = callback;
6857    }
6858
6859    /**
6860     * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
6861     * android.view.View, String)} was used to start an Activity, <var>callback</var>
6862     * will be called to handle shared elements on the <i>launching</i> Activity. Most
6863     * calls will only come when returning from the started Activity.
6864     * This requires {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
6865     *
6866     * @param callback Used to manipulate shared element transitions on the launching Activity.
6867     */
6868    public void setExitSharedElementCallback(SharedElementCallback callback) {
6869        if (callback == null) {
6870            callback = SharedElementCallback.NULL_CALLBACK;
6871        }
6872        mExitTransitionListener = callback;
6873    }
6874
6875    /**
6876     * Postpone the entering activity transition when Activity was started with
6877     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
6878     * android.util.Pair[])}.
6879     * <p>This method gives the Activity the ability to delay starting the entering and
6880     * shared element transitions until all data is loaded. Until then, the Activity won't
6881     * draw into its window, leaving the window transparent. This may also cause the
6882     * returning animation to be delayed until data is ready. This method should be
6883     * called in {@link #onCreate(android.os.Bundle)} or in
6884     * {@link #onActivityReenter(int, android.content.Intent)}.
6885     * {@link #startPostponedEnterTransition()} must be called to allow the Activity to
6886     * start the transitions. If the Activity did not use
6887     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
6888     * android.util.Pair[])}, then this method does nothing.</p>
6889     */
6890    public void postponeEnterTransition() {
6891        mActivityTransitionState.postponeEnterTransition();
6892    }
6893
6894    /**
6895     * Begin postponed transitions after {@link #postponeEnterTransition()} was called.
6896     * If postponeEnterTransition() was called, you must call startPostponedEnterTransition()
6897     * to have your Activity start drawing.
6898     */
6899    public void startPostponedEnterTransition() {
6900        mActivityTransitionState.startPostponedEnterTransition();
6901    }
6902
6903    /**
6904     * Create {@link DragAndDropPermissions} object bound to this activity and controlling the
6905     * access permissions for content URIs associated with the {@link DragEvent}.
6906     * @param event Drag event
6907     * @return The {@link DragAndDropPermissions} object used to control access to the content URIs.
6908     * Null if no content URIs are associated with the event or if permissions could not be granted.
6909     */
6910    public DragAndDropPermissions requestDragAndDropPermissions(DragEvent event) {
6911        DragAndDropPermissions dragAndDropPermissions = DragAndDropPermissions.obtain(event);
6912        if (dragAndDropPermissions != null && dragAndDropPermissions.take(getActivityToken())) {
6913            return dragAndDropPermissions;
6914        }
6915        return null;
6916    }
6917
6918    // ------------------ Internal API ------------------
6919
6920    final void setParent(Activity parent) {
6921        mParent = parent;
6922    }
6923
6924    final void attach(Context context, ActivityThread aThread,
6925            Instrumentation instr, IBinder token, int ident,
6926            Application application, Intent intent, ActivityInfo info,
6927            CharSequence title, Activity parent, String id,
6928            NonConfigurationInstances lastNonConfigurationInstances,
6929            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
6930            Window window, ActivityConfigCallback activityConfigCallback) {
6931        attachBaseContext(context);
6932
6933        mFragments.attachHost(null /*parent*/);
6934
6935        mWindow = new PhoneWindow(this, window, activityConfigCallback);
6936        mWindow.setWindowControllerCallback(this);
6937        mWindow.setCallback(this);
6938        mWindow.setOnWindowDismissedCallback(this);
6939        mWindow.getLayoutInflater().setPrivateFactory(this);
6940        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
6941            mWindow.setSoftInputMode(info.softInputMode);
6942        }
6943        if (info.uiOptions != 0) {
6944            mWindow.setUiOptions(info.uiOptions);
6945        }
6946        mUiThread = Thread.currentThread();
6947
6948        mMainThread = aThread;
6949        mInstrumentation = instr;
6950        mToken = token;
6951        mIdent = ident;
6952        mApplication = application;
6953        mIntent = intent;
6954        mReferrer = referrer;
6955        mComponent = intent.getComponent();
6956        mActivityInfo = info;
6957        mTitle = title;
6958        mParent = parent;
6959        mEmbeddedID = id;
6960        mLastNonConfigurationInstances = lastNonConfigurationInstances;
6961        if (voiceInteractor != null) {
6962            if (lastNonConfigurationInstances != null) {
6963                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
6964            } else {
6965                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
6966                        Looper.myLooper());
6967            }
6968        }
6969
6970        mWindow.setWindowManager(
6971                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
6972                mToken, mComponent.flattenToString(),
6973                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
6974        if (mParent != null) {
6975            mWindow.setContainer(mParent.getWindow());
6976        }
6977        mWindowManager = mWindow.getWindowManager();
6978        mCurrentConfig = config;
6979
6980        mWindow.setColorMode(info.colorMode);
6981    }
6982
6983    /** @hide */
6984    public final IBinder getActivityToken() {
6985        return mParent != null ? mParent.getActivityToken() : mToken;
6986    }
6987
6988    final void performCreateCommon() {
6989        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
6990                com.android.internal.R.styleable.Window_windowNoDisplay, false);
6991        mFragments.dispatchActivityCreated();
6992        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
6993    }
6994
6995    final void performCreate(Bundle icicle) {
6996        restoreHasCurrentPermissionRequest(icicle);
6997        onCreate(icicle);
6998        mActivityTransitionState.readState(icicle);
6999        performCreateCommon();
7000    }
7001
7002    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
7003        restoreHasCurrentPermissionRequest(icicle);
7004        onCreate(icicle, persistentState);
7005        mActivityTransitionState.readState(icicle);
7006        performCreateCommon();
7007    }
7008
7009    final void performStart() {
7010        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
7011        mFragments.noteStateNotSaved();
7012        mCalled = false;
7013        mFragments.execPendingActions();
7014        mInstrumentation.callActivityOnStart(this);
7015        if (!mCalled) {
7016            throw new SuperNotCalledException(
7017                "Activity " + mComponent.toShortString() +
7018                " did not call through to super.onStart()");
7019        }
7020        mFragments.dispatchStart();
7021        mFragments.reportLoaderStart();
7022
7023        // This property is set for all builds except final release
7024        boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1;
7025        boolean isAppDebuggable =
7026                (mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
7027
7028        if (isAppDebuggable || isDlwarningEnabled) {
7029            String dlwarning = getDlWarning();
7030            if (dlwarning != null) {
7031                String appName = getApplicationInfo().loadLabel(getPackageManager())
7032                        .toString();
7033                String warning = "Detected problems with app native libraries\n" +
7034                                 "(please consult log for detail):\n" + dlwarning;
7035                if (isAppDebuggable) {
7036                      new AlertDialog.Builder(this).
7037                          setTitle(appName).
7038                          setMessage(warning).
7039                          setPositiveButton(android.R.string.ok, null).
7040                          setCancelable(false).
7041                          show();
7042                } else {
7043                    Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show();
7044                }
7045            }
7046        }
7047
7048        mActivityTransitionState.enterReady(this);
7049    }
7050
7051    final void performRestart() {
7052        mFragments.noteStateNotSaved();
7053
7054        if (mToken != null && mParent == null) {
7055            // No need to check mStopped, the roots will check if they were actually stopped.
7056            WindowManagerGlobal.getInstance().setStoppedState(mToken, false /* stopped */);
7057        }
7058
7059        if (mStopped) {
7060            mStopped = false;
7061
7062            synchronized (mManagedCursors) {
7063                final int N = mManagedCursors.size();
7064                for (int i=0; i<N; i++) {
7065                    ManagedCursor mc = mManagedCursors.get(i);
7066                    if (mc.mReleased || mc.mUpdated) {
7067                        if (!mc.mCursor.requery()) {
7068                            if (getApplicationInfo().targetSdkVersion
7069                                    >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
7070                                throw new IllegalStateException(
7071                                        "trying to requery an already closed cursor  "
7072                                        + mc.mCursor);
7073                            }
7074                        }
7075                        mc.mReleased = false;
7076                        mc.mUpdated = false;
7077                    }
7078                }
7079            }
7080
7081            mCalled = false;
7082            mInstrumentation.callActivityOnRestart(this);
7083            if (!mCalled) {
7084                throw new SuperNotCalledException(
7085                    "Activity " + mComponent.toShortString() +
7086                    " did not call through to super.onRestart()");
7087            }
7088            performStart();
7089        }
7090    }
7091
7092    final void performResume() {
7093        performRestart();
7094
7095        mFragments.execPendingActions();
7096
7097        mLastNonConfigurationInstances = null;
7098
7099        mCalled = false;
7100        // mResumed is set by the instrumentation
7101        mInstrumentation.callActivityOnResume(this);
7102        if (!mCalled) {
7103            throw new SuperNotCalledException(
7104                "Activity " + mComponent.toShortString() +
7105                " did not call through to super.onResume()");
7106        }
7107
7108        // invisible activities must be finished before onResume() completes
7109        if (!mVisibleFromClient && !mFinished) {
7110            Log.w(TAG, "An activity without a UI must call finish() before onResume() completes");
7111            if (getApplicationInfo().targetSdkVersion
7112                    > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
7113                throw new IllegalStateException(
7114                        "Activity " + mComponent.toShortString() +
7115                        " did not call finish() prior to onResume() completing");
7116            }
7117        }
7118
7119        // Now really resume, and install the current status bar and menu.
7120        mCalled = false;
7121
7122        mFragments.dispatchResume();
7123        mFragments.execPendingActions();
7124
7125        onPostResume();
7126        if (!mCalled) {
7127            throw new SuperNotCalledException(
7128                "Activity " + mComponent.toShortString() +
7129                " did not call through to super.onPostResume()");
7130        }
7131    }
7132
7133    final void performPause() {
7134        mDoReportFullyDrawn = false;
7135        mFragments.dispatchPause();
7136        mCalled = false;
7137        onPause();
7138        mResumed = false;
7139        if (!mCalled && getApplicationInfo().targetSdkVersion
7140                >= android.os.Build.VERSION_CODES.GINGERBREAD) {
7141            throw new SuperNotCalledException(
7142                    "Activity " + mComponent.toShortString() +
7143                    " did not call through to super.onPause()");
7144        }
7145        mResumed = false;
7146    }
7147
7148    final void performUserLeaving() {
7149        onUserInteraction();
7150        onUserLeaveHint();
7151    }
7152
7153    final void performStop(boolean preserveWindow) {
7154        mDoReportFullyDrawn = false;
7155        mFragments.doLoaderStop(mChangingConfigurations /*retain*/);
7156
7157        if (!mStopped) {
7158            if (mWindow != null) {
7159                mWindow.closeAllPanels();
7160            }
7161
7162            // If we're preserving the window, don't setStoppedState to true, since we
7163            // need the window started immediately again. Stopping the window will
7164            // destroys hardware resources and causes flicker.
7165            if (!preserveWindow && mToken != null && mParent == null) {
7166                WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
7167            }
7168
7169            mFragments.dispatchStop();
7170
7171            mCalled = false;
7172            mInstrumentation.callActivityOnStop(this);
7173            if (!mCalled) {
7174                throw new SuperNotCalledException(
7175                    "Activity " + mComponent.toShortString() +
7176                    " did not call through to super.onStop()");
7177            }
7178
7179            synchronized (mManagedCursors) {
7180                final int N = mManagedCursors.size();
7181                for (int i=0; i<N; i++) {
7182                    ManagedCursor mc = mManagedCursors.get(i);
7183                    if (!mc.mReleased) {
7184                        mc.mCursor.deactivate();
7185                        mc.mReleased = true;
7186                    }
7187                }
7188            }
7189
7190            mStopped = true;
7191        }
7192        mResumed = false;
7193    }
7194
7195    final void performDestroy() {
7196        mDestroyed = true;
7197        mWindow.destroy();
7198        mFragments.dispatchDestroy();
7199        onDestroy();
7200        mFragments.doLoaderDestroy();
7201        if (mVoiceInteractor != null) {
7202            mVoiceInteractor.detachActivity();
7203        }
7204    }
7205
7206    final void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode,
7207            Configuration newConfig) {
7208        if (DEBUG_LIFECYCLE) Slog.v(TAG,
7209                "dispatchMultiWindowModeChanged " + this + ": " + isInMultiWindowMode
7210                        + " " + newConfig);
7211        mFragments.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
7212        if (mWindow != null) {
7213            mWindow.onMultiWindowModeChanged();
7214        }
7215        onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
7216    }
7217
7218    final void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode,
7219            Configuration newConfig) {
7220        if (DEBUG_LIFECYCLE) Slog.v(TAG,
7221                "dispatchPictureInPictureModeChanged " + this + ": " + isInPictureInPictureMode
7222                        + " " + newConfig);
7223        mFragments.dispatchPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
7224        onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
7225    }
7226
7227    /**
7228     * @hide
7229     */
7230    public final boolean isResumed() {
7231        return mResumed;
7232    }
7233
7234    private void storeHasCurrentPermissionRequest(Bundle bundle) {
7235        if (bundle != null && mHasCurrentPermissionsRequest) {
7236            bundle.putBoolean(HAS_CURENT_PERMISSIONS_REQUEST_KEY, true);
7237        }
7238    }
7239
7240    private void restoreHasCurrentPermissionRequest(Bundle bundle) {
7241        if (bundle != null) {
7242            mHasCurrentPermissionsRequest = bundle.getBoolean(
7243                    HAS_CURENT_PERMISSIONS_REQUEST_KEY, false);
7244        }
7245    }
7246
7247    void dispatchActivityResult(String who, int requestCode,
7248        int resultCode, Intent data) {
7249        if (false) Log.v(
7250            TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode
7251            + ", resCode=" + resultCode + ", data=" + data);
7252        mFragments.noteStateNotSaved();
7253        if (who == null) {
7254            onActivityResult(requestCode, resultCode, data);
7255        } else if (who.startsWith(REQUEST_PERMISSIONS_WHO_PREFIX)) {
7256            who = who.substring(REQUEST_PERMISSIONS_WHO_PREFIX.length());
7257            if (TextUtils.isEmpty(who)) {
7258                dispatchRequestPermissionsResult(requestCode, data);
7259            } else {
7260                Fragment frag = mFragments.findFragmentByWho(who);
7261                if (frag != null) {
7262                    dispatchRequestPermissionsResultToFragment(requestCode, data, frag);
7263                }
7264            }
7265        } else if (who.startsWith("@android:view:")) {
7266            ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
7267                    getActivityToken());
7268            for (ViewRootImpl viewRoot : views) {
7269                if (viewRoot.getView() != null
7270                        && viewRoot.getView().dispatchActivityResult(
7271                                who, requestCode, resultCode, data)) {
7272                    return;
7273                }
7274            }
7275        } else if (who.startsWith(AUTO_FILL_AUTH_WHO_PREFIX)) {
7276            Intent resultData = (resultCode == Activity.RESULT_OK) ? data : null;
7277            getAutofillManager().onAuthenticationResult(resultData);
7278        } else {
7279            Fragment frag = mFragments.findFragmentByWho(who);
7280            if (frag != null) {
7281                frag.onActivityResult(requestCode, resultCode, data);
7282            }
7283        }
7284    }
7285
7286    /**
7287     * Request to put this Activity in a mode where the user is locked to the
7288     * current task.
7289     *
7290     * This will prevent the user from launching other apps, going to settings, or reaching the
7291     * home screen. This does not include those apps whose {@link android.R.attr#lockTaskMode}
7292     * values permit launching while locked.
7293     *
7294     * If {@link DevicePolicyManager#isLockTaskPermitted(String)} returns true or
7295     * lockTaskMode=lockTaskModeAlways for this component then the app will go directly into
7296     * Lock Task mode. The user will not be able to exit this mode until
7297     * {@link Activity#stopLockTask()} is called.
7298     *
7299     * If {@link DevicePolicyManager#isLockTaskPermitted(String)} returns false
7300     * then the system will prompt the user with a dialog requesting permission to enter
7301     * this mode.  When entered through this method the user can exit at any time through
7302     * an action described by the request dialog.  Calling stopLockTask will also exit the
7303     * mode.
7304     *
7305     * @see android.R.attr#lockTaskMode
7306     */
7307    public void startLockTask() {
7308        try {
7309            ActivityManager.getService().startLockTaskModeByToken(mToken);
7310        } catch (RemoteException e) {
7311        }
7312    }
7313
7314    /**
7315     * Allow the user to switch away from the current task.
7316     *
7317     * Called to end the mode started by {@link Activity#startLockTask}. This
7318     * can only be called by activities that have successfully called
7319     * startLockTask previously.
7320     *
7321     * This will allow the user to exit this app and move onto other activities.
7322     * <p>Note: This method should only be called when the activity is user-facing. That is,
7323     * between onResume() and onPause().
7324     * <p>Note: If there are other tasks below this one that are also locked then calling this
7325     * method will immediately finish this task and resume the previous locked one, remaining in
7326     * lockTask mode.
7327     *
7328     * @see android.R.attr#lockTaskMode
7329     * @see ActivityManager#getLockTaskModeState()
7330     */
7331    public void stopLockTask() {
7332        try {
7333            ActivityManager.getService().stopLockTaskMode();
7334        } catch (RemoteException e) {
7335        }
7336    }
7337
7338    /**
7339     * Shows the user the system defined message for telling the user how to exit
7340     * lock task mode. The task containing this activity must be in lock task mode at the time
7341     * of this call for the message to be displayed.
7342     */
7343    public void showLockTaskEscapeMessage() {
7344        try {
7345            ActivityManager.getService().showLockTaskEscapeMessage(mToken);
7346        } catch (RemoteException e) {
7347        }
7348    }
7349
7350    /**
7351     * Check whether the caption on freeform windows is displayed directly on the content.
7352     *
7353     * @return True if caption is displayed on content, false if it pushes the content down.
7354     *
7355     * @see #setOverlayWithDecorCaptionEnabled(boolean)
7356     * @hide
7357     */
7358    public boolean isOverlayWithDecorCaptionEnabled() {
7359        return mWindow.isOverlayWithDecorCaptionEnabled();
7360    }
7361
7362    /**
7363     * Set whether the caption should displayed directly on the content rather than push it down.
7364     *
7365     * This affects only freeform windows since they display the caption and only the main
7366     * window of the activity. The caption is used to drag the window around and also shows
7367     * maximize and close action buttons.
7368     * @hide
7369     */
7370    public void setOverlayWithDecorCaptionEnabled(boolean enabled) {
7371        mWindow.setOverlayWithDecorCaptionEnabled(enabled);
7372    }
7373
7374    /**
7375     * Interface for informing a translucent {@link Activity} once all visible activities below it
7376     * have completed drawing. This is necessary only after an {@link Activity} has been made
7377     * opaque using {@link Activity#convertFromTranslucent()} and before it has been drawn
7378     * translucent again following a call to {@link
7379     * Activity#convertToTranslucent(android.app.Activity.TranslucentConversionListener,
7380     * ActivityOptions)}
7381     *
7382     * @hide
7383     */
7384    @SystemApi
7385    public interface TranslucentConversionListener {
7386        /**
7387         * Callback made following {@link Activity#convertToTranslucent} once all visible Activities
7388         * below the top one have been redrawn. Following this callback it is safe to make the top
7389         * Activity translucent because the underlying Activity has been drawn.
7390         *
7391         * @param drawComplete True if the background Activity has drawn itself. False if a timeout
7392         * occurred waiting for the Activity to complete drawing.
7393         *
7394         * @see Activity#convertFromTranslucent()
7395         * @see Activity#convertToTranslucent(TranslucentConversionListener, ActivityOptions)
7396         */
7397        public void onTranslucentConversionComplete(boolean drawComplete);
7398    }
7399
7400    private void dispatchRequestPermissionsResult(int requestCode, Intent data) {
7401        mHasCurrentPermissionsRequest = false;
7402        // If the package installer crashed we may have not data - best effort.
7403        String[] permissions = (data != null) ? data.getStringArrayExtra(
7404                PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0];
7405        final int[] grantResults = (data != null) ? data.getIntArrayExtra(
7406                PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0];
7407        onRequestPermissionsResult(requestCode, permissions, grantResults);
7408    }
7409
7410    private void dispatchRequestPermissionsResultToFragment(int requestCode, Intent data,
7411            Fragment fragment) {
7412        // If the package installer crashed we may have not data - best effort.
7413        String[] permissions = (data != null) ? data.getStringArrayExtra(
7414                PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0];
7415        final int[] grantResults = (data != null) ? data.getIntArrayExtra(
7416                PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0];
7417        fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
7418    }
7419
7420    /** @hide */
7421    @Override
7422    final public void autofillCallbackAuthenticate(IntentSender intent, Intent fillInIntent) {
7423        try {
7424            startIntentSenderForResultInner(intent, AUTO_FILL_AUTH_WHO_PREFIX,
7425                    0, fillInIntent, 0, 0, null);
7426        } catch (IntentSender.SendIntentException e) {
7427            Log.e(TAG, "authenticate() failed for intent:" + intent, e);
7428        }
7429    }
7430
7431    /** @hide */
7432    @Override
7433    final public void autofillCallbackResetableStateAvailable() {
7434        mAutoFillResetNeeded = true;
7435    }
7436
7437    /** @hide */
7438    @Override
7439    final public boolean autofillCallbackRequestShowFillUi(@NonNull View anchor, int width,
7440            int height, @Nullable Rect anchorBounds, IAutofillWindowPresenter presenter) {
7441        final Rect actualAnchorBounds = new Rect();
7442        anchor.getBoundsOnScreen(actualAnchorBounds);
7443
7444        final int offsetX = (anchorBounds != null)
7445                ? anchorBounds.left - actualAnchorBounds.left : 0;
7446        int offsetY = (anchorBounds != null)
7447                ? anchorBounds.bottom - actualAnchorBounds.bottom : 0;
7448
7449        final boolean wasShowing;
7450
7451        if (mAutofillPopupWindow == null) {
7452            wasShowing = false;
7453            mAutofillPopupWindow = new AutofillPopupWindow(presenter);
7454        } else {
7455            wasShowing = mAutofillPopupWindow.isShowing();
7456        }
7457        mAutofillPopupWindow.update(anchor, offsetX, offsetY, width, height, anchorBounds,
7458                actualAnchorBounds);
7459
7460        return !wasShowing && mAutofillPopupWindow.isShowing();
7461    }
7462
7463    /** @hide */
7464    @Override
7465    final public boolean autofillCallbackRequestHideFillUi() {
7466        if (mAutofillPopupWindow == null) {
7467            return false;
7468        }
7469        mAutofillPopupWindow.dismiss();
7470        mAutofillPopupWindow = null;
7471        return true;
7472    }
7473
7474    /** @hide */
7475    @NonNull public View[] findViewsByAccessibilityIdTraversal(@NonNull int[] viewIds) {
7476        final View[] views = new View[viewIds.length];
7477        final ArrayList<ViewRootImpl> roots =
7478                WindowManagerGlobal.getInstance().getRootViews(getActivityToken());
7479
7480        for (int rootNum = 0; rootNum < roots.size(); rootNum++) {
7481            final View rootView = roots.get(rootNum).getView();
7482
7483            if (rootView != null) {
7484                for (int viewNum = 0; viewNum < viewIds.length; viewNum++) {
7485                    if (views[viewNum] == null) {
7486                        views[viewNum] = rootView.findViewByAccessibilityIdTraversal(
7487                                viewIds[viewNum]);
7488                    }
7489                }
7490            }
7491        }
7492
7493        return views;
7494    }
7495
7496    /** @hide */
7497    @Override
7498    @NonNull public boolean[] getViewVisibility(@NonNull int[] viewIds) {
7499        final boolean[] isVisible = new boolean[viewIds.length];
7500        final View views[] = findViewsByAccessibilityIdTraversal(viewIds);
7501
7502        for (int i = 0; i < viewIds.length; i++) {
7503            View view = views[i];
7504            if (view == null) {
7505                isVisible[i] = false;
7506                continue;
7507            }
7508
7509            isVisible[i] = true;
7510
7511            // Check if the view is visible by checking all parents
7512            while (true) {
7513                if (view instanceof DecorView && view.getViewRootImpl() == view.getParent()) {
7514                    break;
7515                }
7516
7517                if (view.getVisibility() != View.VISIBLE) {
7518                    isVisible[i] = false;
7519                    break;
7520                }
7521
7522                if (view.getParent() instanceof View) {
7523                    view = (View) view.getParent();
7524                } else {
7525                    break;
7526                }
7527            }
7528        }
7529
7530        return isVisible;
7531    }
7532
7533    /** @hide */
7534    @Override
7535    public boolean isVisibleForAutofill() {
7536        return !mStopped;
7537    }
7538
7539    /**
7540     * If set to true, this indicates to the system that it should never take a
7541     * screenshot of the activity to be used as a representation while it is not in a started state.
7542     * <p>
7543     * Note that the system may use the window background of the theme instead to represent
7544     * the window when it is not running.
7545     * <p>
7546     * Also note that in comparison to {@link android.view.WindowManager.LayoutParams#FLAG_SECURE},
7547     * this only affects the behavior when the activity's screenshot would be used as a
7548     * representation when the activity is not in a started state, i.e. in Overview. The system may
7549     * still take screenshots of the activity in other contexts; for example, when the user takes a
7550     * screenshot of the entire screen, or when the active
7551     * {@link android.service.voice.VoiceInteractionService} requests a screenshot via
7552     * {@link android.service.voice.VoiceInteractionSession#SHOW_WITH_SCREENSHOT}.
7553     *
7554     * @param disable {@code true} to disable preview screenshots; {@code false} otherwise.
7555     * @hide
7556     */
7557    @SystemApi
7558    public void setDisablePreviewScreenshots(boolean disable) {
7559        try {
7560            ActivityManager.getService().setDisablePreviewScreenshots(mToken, disable);
7561        } catch (RemoteException e) {
7562            Log.e(TAG, "Failed to call setDisablePreviewScreenshots", e);
7563        }
7564    }
7565
7566    class HostCallbacks extends FragmentHostCallback<Activity> {
7567        public HostCallbacks() {
7568            super(Activity.this /*activity*/);
7569        }
7570
7571        @Override
7572        public void onDump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
7573            Activity.this.dump(prefix, fd, writer, args);
7574        }
7575
7576        @Override
7577        public boolean onShouldSaveFragmentState(Fragment fragment) {
7578            return !isFinishing();
7579        }
7580
7581        @Override
7582        public LayoutInflater onGetLayoutInflater() {
7583            final LayoutInflater result = Activity.this.getLayoutInflater();
7584            if (onUseFragmentManagerInflaterFactory()) {
7585                return result.cloneInContext(Activity.this);
7586            }
7587            return result;
7588        }
7589
7590        @Override
7591        public boolean onUseFragmentManagerInflaterFactory() {
7592            // Newer platform versions use the child fragment manager's LayoutInflaterFactory.
7593            return getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP;
7594        }
7595
7596        @Override
7597        public Activity onGetHost() {
7598            return Activity.this;
7599        }
7600
7601        @Override
7602        public void onInvalidateOptionsMenu() {
7603            Activity.this.invalidateOptionsMenu();
7604        }
7605
7606        @Override
7607        public void onStartActivityFromFragment(Fragment fragment, Intent intent, int requestCode,
7608                Bundle options) {
7609            Activity.this.startActivityFromFragment(fragment, intent, requestCode, options);
7610        }
7611
7612        @Override
7613        public void onStartActivityAsUserFromFragment(
7614                Fragment fragment, Intent intent, int requestCode, Bundle options,
7615                UserHandle user) {
7616            Activity.this.startActivityAsUserFromFragment(
7617                    fragment, intent, requestCode, options, user);
7618        }
7619
7620        @Override
7621        public void onStartIntentSenderFromFragment(Fragment fragment, IntentSender intent,
7622                int requestCode, @Nullable Intent fillInIntent, int flagsMask, int flagsValues,
7623                int extraFlags, Bundle options) throws IntentSender.SendIntentException {
7624            if (mParent == null) {
7625                startIntentSenderForResultInner(intent, fragment.mWho, requestCode, fillInIntent,
7626                        flagsMask, flagsValues, options);
7627            } else if (options != null) {
7628                mParent.startIntentSenderFromChildFragment(fragment, intent, requestCode,
7629                        fillInIntent, flagsMask, flagsValues, extraFlags, options);
7630            }
7631        }
7632
7633        @Override
7634        public void onRequestPermissionsFromFragment(Fragment fragment, String[] permissions,
7635                int requestCode) {
7636            String who = REQUEST_PERMISSIONS_WHO_PREFIX + fragment.mWho;
7637            Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
7638            startActivityForResult(who, intent, requestCode, null);
7639        }
7640
7641        @Override
7642        public boolean onHasWindowAnimations() {
7643            return getWindow() != null;
7644        }
7645
7646        @Override
7647        public int onGetWindowAnimations() {
7648            final Window w = getWindow();
7649            return (w == null) ? 0 : w.getAttributes().windowAnimations;
7650        }
7651
7652        @Override
7653        public void onAttachFragment(Fragment fragment) {
7654            Activity.this.onAttachFragment(fragment);
7655        }
7656
7657        @Nullable
7658        @Override
7659        public <T extends View> T onFindViewById(int id) {
7660            return Activity.this.findViewById(id);
7661        }
7662
7663        @Override
7664        public boolean onHasView() {
7665            final Window w = getWindow();
7666            return (w != null && w.peekDecorView() != null);
7667        }
7668    }
7669}
7670