1 /* 2 * Copyright (C) 2019 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 17 package android.app; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SuppressLint; 23 import android.content.Intent; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 27 import java.lang.annotation.ElementType; 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.lang.annotation.Target; 31 import java.util.HashMap; 32 import java.util.Map; 33 34 /** 35 * Provide information related to a processes startup. 36 * 37 * @hide 38 */ 39 public final class ApplicationStartInfo implements Parcelable { 40 41 /** 42 * State indicating process startup has started. Some information is available in 43 * {@link ApplicationStartInfo} and more will be added. 44 */ 45 public static final int STARTUP_STATE_STARTED = 0; 46 47 /** 48 * State indicating process startup has failed. Startup information in 49 * {@link ApplicationStartInfo} is incomplete, but no more will be added. 50 */ 51 public static final int STARTUP_STATE_ERROR = 1; 52 53 /** 54 * State indicating process startup has made it to first frame draw. Startup 55 * information in {@link ApplicationStartInfo} is complete with potential exception 56 * of fully drawn timestamp which is not guaranteed to be set. 57 */ 58 public static final int STARTUP_STATE_FIRST_FRAME_DRAWN = 2; 59 60 /** Process started due to alarm. */ 61 public static final int START_REASON_ALARM = 0; 62 63 /** Process started to run backup. */ 64 public static final int START_REASON_BACKUP = 1; 65 66 /** Process started due to boot complete. */ 67 public static final int START_REASON_BOOT_COMPLETE = 2; 68 69 /** Process started due to broadcast received. */ 70 public static final int START_REASON_BROADCAST = 3; 71 72 /** Process started due to access of ContentProvider */ 73 public static final int START_REASON_CONTENT_PROVIDER = 4; 74 75 /** * Process started to run scheduled job. */ 76 public static final int START_REASON_JOB = 5; 77 78 /** Process started due to click app icon or widget from launcher. */ 79 public static final int START_REASON_LAUNCHER = 6; 80 81 /** Process started not for any of the listed reasons. */ 82 public static final int START_REASON_OTHER = 7; 83 84 /** Process started due to push message. */ 85 public static final int START_REASON_PUSH = 8; 86 87 /** Process started to resume activity. */ 88 public static final int START_REASON_RESUMED_ACTIVITY = 9; 89 90 /** Process service started. */ 91 public static final int START_REASON_SERVICE = 10; 92 93 /** Process started due to Activity started for any reason not explicitly listed. */ 94 public static final int START_REASON_START_ACTIVITY = 11; 95 96 /** Process started from scratch. */ 97 public static final int START_TYPE_COLD = 0; 98 99 /** Process retained minimally SavedInstanceState. */ 100 public static final int START_TYPE_WARM = 1; 101 102 /** Process brought back to foreground. */ 103 public static final int START_TYPE_HOT = 2; 104 105 /** 106 * Default. The system always creates a new instance of the activity in the target task and 107 * routes the intent to it. 108 */ 109 public static final int LAUNCH_MODE_STANDARD = 0; 110 111 /** 112 * If an instance of the activity already exists at the top of the target task, the system 113 * routes the intent to that instance through a call to its onNewIntent() method, rather than 114 * creating a new instance of the activity. 115 */ 116 public static final int LAUNCH_MODE_SINGLE_TOP = 1; 117 118 /** 119 * The system creates the activity at the root of a new task or locates the activity on an 120 * existing task with the same affinity. If an instance of the activity already exists and is at 121 * the root of the task, the system routes the intent to existing instance through a call to its 122 * onNewIntent() method, rather than creating a new one. 123 */ 124 public static final int LAUNCH_MODE_SINGLE_INSTANCE = 2; 125 126 /** 127 * Same as "singleTask", except that the system doesn't launch any other activities into the 128 * task holding the instance. The activity is always the single and only member of its task. 129 */ 130 public static final int LAUNCH_MODE_SINGLE_TASK = 3; 131 132 /** 133 * The activity can only be running as the root activity of the task, the first activity that 134 * created the task, and therefore there will only be one instance of this activity in a task; 135 * but activity can be instantiated multiple times in different tasks. 136 */ 137 public static final int LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK = 4; 138 139 /** Clock monotonic timestamp of launch started. */ 140 public static final int START_TIMESTAMP_LAUNCH = 0; 141 142 /** Clock monotonic timestamp of finish java classloading. */ 143 public static final int START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE = 1; 144 145 /** Clock monotonic timestamp of Application onCreate called. */ 146 public static final int START_TIMESTAMP_APPLICATION_ONCREATE = 2; 147 148 /** Clock monotonic timestamp of bindApplication called. */ 149 public static final int START_TIMESTAMP_BIND_APPLICATION = 3; 150 151 /** Clock monotonic timestamp of first frame drawn. */ 152 public static final int START_TIMESTAMP_FIRST_FRAME = 4; 153 154 /** Clock monotonic timestamp of reportFullyDrawn called by application. */ 155 public static final int START_TIMESTAMP_FULLY_DRAWN = 5; 156 157 /** 158 * @see #getStartupState 159 */ 160 private @StartupState int mStartupState; 161 162 /** 163 * @see #getPid 164 */ 165 private int mPid; 166 167 /** 168 * @see #getRealUid 169 */ 170 private int mRealUid; 171 172 /** 173 * @see #getPackageUid 174 */ 175 private int mPackageUid; 176 177 /** 178 * @see #getDefiningUid 179 */ 180 private int mDefiningUid; 181 182 /** 183 * @see #getProcessName 184 */ 185 private String mProcessName; 186 187 /** 188 * @see #getReason 189 */ 190 private @StartReason int mReason; 191 192 /** 193 * @see #getStartupTimestamps 194 */ 195 private Map<@StartupTimestamp Integer, Long> mStartupTimestampsNs; 196 197 /** 198 * @see #getStartType 199 */ 200 private @StartType int mStartType; 201 202 /** 203 * @see #getStartIntent 204 */ 205 private Intent mStartIntent; 206 207 /** 208 * @see #getLaunchMode 209 */ 210 private @LaunchMode int mLaunchMode; 211 212 /** 213 * @hide * 214 */ 215 @IntDef( 216 prefix = {"STARTUP_STATE_"}, 217 value = { 218 STARTUP_STATE_STARTED, 219 STARTUP_STATE_ERROR, 220 STARTUP_STATE_FIRST_FRAME_DRAWN, 221 }) 222 @Retention(RetentionPolicy.SOURCE) 223 public @interface StartupState {} 224 225 /** 226 * @hide * 227 */ 228 @IntDef( 229 prefix = {"START_REASON_"}, 230 value = { 231 START_REASON_ALARM, 232 START_REASON_BACKUP, 233 START_REASON_BOOT_COMPLETE, 234 START_REASON_BROADCAST, 235 START_REASON_CONTENT_PROVIDER, 236 START_REASON_JOB, 237 START_REASON_LAUNCHER, 238 START_REASON_OTHER, 239 START_REASON_PUSH, 240 START_REASON_RESUMED_ACTIVITY, 241 START_REASON_SERVICE, 242 START_REASON_START_ACTIVITY, 243 }) 244 @Retention(RetentionPolicy.SOURCE) 245 public @interface StartReason {} 246 247 /** 248 * @hide * 249 */ 250 @IntDef( 251 prefix = {"START_TYPE_"}, 252 value = { 253 START_TYPE_COLD, 254 START_TYPE_WARM, 255 START_TYPE_HOT, 256 }) 257 @Retention(RetentionPolicy.SOURCE) 258 public @interface StartType {} 259 260 /** 261 * @hide * 262 */ 263 @IntDef( 264 prefix = {"LAUNCH_MODE_"}, 265 value = { 266 LAUNCH_MODE_STANDARD, 267 LAUNCH_MODE_SINGLE_TOP, 268 LAUNCH_MODE_SINGLE_INSTANCE, 269 LAUNCH_MODE_SINGLE_TASK, 270 LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK, 271 }) 272 @Retention(RetentionPolicy.SOURCE) 273 public @interface LaunchMode {} 274 275 /** 276 * @hide * 277 */ 278 @IntDef( 279 prefix = {"START_TIMESTAMP_"}, 280 value = { 281 START_TIMESTAMP_LAUNCH, 282 START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE, 283 START_TIMESTAMP_APPLICATION_ONCREATE, 284 START_TIMESTAMP_BIND_APPLICATION, 285 START_TIMESTAMP_FULLY_DRAWN, 286 }) 287 @Retention(RetentionPolicy.SOURCE) 288 @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) 289 public @interface StartupTimestamp {} 290 291 /** 292 * @see #getStartupState 293 * @hide 294 */ setStartupState(final @StartupState int startupState)295 public void setStartupState(final @StartupState int startupState) { 296 mStartupState = startupState; 297 } 298 299 /** 300 * @see #getPid 301 * @hide 302 */ setPid(final int pid)303 public void setPid(final int pid) { 304 mPid = pid; 305 } 306 307 /** 308 * @see #getRealUid 309 * @hide 310 */ setRealUid(final int uid)311 public void setRealUid(final int uid) { 312 mRealUid = uid; 313 } 314 315 /** 316 * @see #getPackageUid 317 * @hide 318 */ setPackageUid(final int uid)319 public void setPackageUid(final int uid) { 320 mPackageUid = uid; 321 } 322 323 /** 324 * @see #getDefiningUid 325 * @hide 326 */ setDefiningUid(final int uid)327 public void setDefiningUid(final int uid) { 328 mDefiningUid = uid; 329 } 330 331 /** 332 * @see #getProcessName 333 * @hide 334 */ setProcessName(final String processName)335 public void setProcessName(final String processName) { 336 mProcessName = intern(processName); 337 } 338 339 /** 340 * @see #getReason 341 * @hide 342 */ setReason(@tartReason int reason)343 public void setReason(@StartReason int reason) { 344 mReason = reason; 345 } 346 347 /** 348 * @see #getStartupTimestamps 349 * @hide 350 */ addStartupTimestamp(@tartupTimestamp int key, long timestampNs)351 public void addStartupTimestamp(@StartupTimestamp int key, long timestampNs) { 352 if (mStartupTimestampsNs == null) { 353 mStartupTimestampsNs = new HashMap<@StartupTimestamp Integer, Long>(); 354 } 355 mStartupTimestampsNs.put(key, timestampNs); 356 } 357 358 /** 359 * @see #getStartType 360 * @hide 361 */ setStartType(@tartType int startType)362 public void setStartType(@StartType int startType) { 363 mStartType = startType; 364 } 365 366 /** 367 * @see #getStartIntent 368 * @hide 369 */ setIntent(Intent startIntent)370 public void setIntent(Intent startIntent) { 371 mStartIntent = startIntent; 372 } 373 374 /** 375 * @see #getLaunchMode 376 * @hide 377 */ setLaunchMode(@aunchMode int launchMode)378 public void setLaunchMode(@LaunchMode int launchMode) { 379 mLaunchMode = launchMode; 380 } 381 382 /** 383 * Current state of startup. 384 * 385 * Can be used to determine whether the object will have additional fields added as it may be 386 * queried before all data is collected. 387 * 388 * <p class="note"> Note: field will always be set and available.</p> 389 */ getStartupState()390 public @StartupState int getStartupState() { 391 return mStartupState; 392 } 393 394 /** 395 * The process id. 396 * 397 * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> 398 */ getPid()399 public int getPid() { 400 return mPid; 401 } 402 403 /** 404 * The kernel user identifier of the process, most of the time the system uses this to do access 405 * control checks. It's typically the uid of the package where the component is running from, 406 * except the case of isolated process, where this field identifies the kernel user identifier 407 * that this process is actually running with, while the {@link #getPackageUid} identifies the 408 * kernel user identifier that is assigned at the package installation time. 409 * 410 * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> 411 */ getRealUid()412 public int getRealUid() { 413 return mRealUid; 414 } 415 416 /** 417 * Similar to {@link #getRealUid}, it's the kernel user identifier that is assigned at the 418 * package installation time. 419 * 420 * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> 421 */ getPackageUid()422 public int getPackageUid() { 423 return mPackageUid; 424 } 425 426 /** 427 * Return the defining kernel user identifier, maybe different from {@link #getRealUid} and 428 * {@link #getPackageUid}, if an external service has the {@link 429 * android.R.styleable#AndroidManifestService_useAppZygote android:useAppZygote} set to <code> 430 * true</code> and was bound with the flag {@link android.content.Context#BIND_EXTERNAL_SERVICE} 431 * - in this case, this field here will be the kernel user identifier of the external service 432 * provider. 433 * 434 * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> 435 */ getDefiningUid()436 public int getDefiningUid() { 437 return mDefiningUid; 438 } 439 440 /** 441 * The actual process name it was running with. 442 * 443 * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> 444 */ getProcessName()445 public @NonNull String getProcessName() { 446 return mProcessName; 447 } 448 449 /** 450 * The reason code of what triggered the process's start. 451 * 452 * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> 453 */ getReason()454 public @StartReason int getReason() { 455 return mReason; 456 } 457 458 /** 459 * Various clock monotonic timestamps in nanoseconds throughout the startup process. 460 * 461 * <p class="note"> Note: different timestamps will be available for different values of 462 * {@link #getStartupState}: 463 * 464 * (Subsequent rows contain all timestamps of proceding states.) 465 * 466 * For {@link #STARTUP_STATE_STARTED}, timestamp {@link #START_TIMESTAMP_LAUNCH} will be 467 * available. 468 * For {@link #STARTUP_STATE_ERROR}, no additional timestamps are guaranteed available. 469 * For {@link #STARTUP_STATE_FIRST_FRAME_DRAWN}, timestamps 470 * {@link #START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE}, {@link #START_TIMESTAMP_APPLICATION_ONCREATE}, 471 * {@link #START_TIMESTAMP_BIND_APPLICATION}, and {@link #START_TIMESTAMP_FIRST_FRAME} will 472 * additionally be available. 473 * 474 * Timestamp {@link #START_TIMESTAMP_FULLY_DRAWN} is never guaranteed to be available as it is 475 * dependant on devloper calling {@link Activity#reportFullyDrawn}. 476 * </p> 477 */ getStartupTimestamps()478 public @NonNull Map<@StartupTimestamp Integer, Long> getStartupTimestamps() { 479 if (mStartupTimestampsNs == null) { 480 mStartupTimestampsNs = new HashMap<@StartupTimestamp Integer, Long>(); 481 } 482 return mStartupTimestampsNs; 483 } 484 485 /** 486 * The state of the app at startup. 487 * 488 * <p class="note"> Note: field will be set for {@link #getStartupState} value 489 * {@link #STARTUP_STATE_FIRST_FRAME_DRAWN}. Not guaranteed for other states.</p> 490 */ getStartType()491 public @StartType int getStartType() { 492 return mStartType; 493 } 494 495 /** 496 * The intent used to launch the application. 497 * 498 * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> 499 */ 500 @SuppressLint("IntentBuilderName") 501 @Nullable getIntent()502 public Intent getIntent() { 503 return mStartIntent; 504 } 505 506 /** 507 * An instruction on how the activity should be launched. There are five modes that work in 508 * conjunction with activity flags in Intent objects to determine what should happen when the 509 * activity is called upon to handle an intent. 510 * 511 * Modes: 512 * {@link #LAUNCH_MODE_STANDARD} 513 * {@link #LAUNCH_MODE_SINGLE_TOP} 514 * {@link #LAUNCH_MODE_SINGLE_INSTANCE} 515 * {@link #LAUNCH_MODE_SINGLE_TASK} 516 * {@link #LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK} 517 * 518 * <p class="note"> Note: field will be set for any {@link #getStartupState} value.</p> 519 */ getLaunchMode()520 public @LaunchMode int getLaunchMode() { 521 return mLaunchMode; 522 } 523 524 @Override describeContents()525 public int describeContents() { 526 return 0; 527 } 528 529 @Override writeToParcel(@onNull Parcel dest, int flags)530 public void writeToParcel(@NonNull Parcel dest, int flags) { 531 dest.writeInt(mStartupState); 532 dest.writeInt(mPid); 533 dest.writeInt(mRealUid); 534 dest.writeInt(mPackageUid); 535 dest.writeInt(mDefiningUid); 536 dest.writeString(mProcessName); 537 dest.writeInt(mReason); 538 dest.writeInt(mStartupTimestampsNs.size()); 539 for (@StartupTimestamp int key : mStartupTimestampsNs.keySet()) { 540 dest.writeInt(key); 541 dest.writeLong(mStartupTimestampsNs.get(key)); 542 } 543 dest.writeInt(mStartType); 544 dest.writeParcelable(mStartIntent, flags); 545 dest.writeInt(mLaunchMode); 546 } 547 548 /** @hide */ ApplicationStartInfo()549 public ApplicationStartInfo() {} 550 551 /** @hide */ ApplicationStartInfo(ApplicationStartInfo other)552 public ApplicationStartInfo(ApplicationStartInfo other) { 553 mStartupState = other.mStartupState; 554 mPid = other.mPid; 555 mRealUid = other.mRealUid; 556 mPackageUid = other.mPackageUid; 557 mDefiningUid = other.mDefiningUid; 558 mProcessName = other.mProcessName; 559 mReason = other.mReason; 560 mStartupTimestampsNs = other.mStartupTimestampsNs; 561 mStartType = other.mStartType; 562 mStartIntent = other.mStartIntent; 563 mLaunchMode = other.mLaunchMode; 564 } 565 ApplicationStartInfo(@onNull Parcel in)566 private ApplicationStartInfo(@NonNull Parcel in) { 567 mStartupState = in.readInt(); 568 mPid = in.readInt(); 569 mRealUid = in.readInt(); 570 mPackageUid = in.readInt(); 571 mDefiningUid = in.readInt(); 572 mProcessName = intern(in.readString()); 573 mReason = in.readInt(); 574 int starupTimestampCount = in.readInt(); 575 for (int i = 0; i < starupTimestampCount; i++) { 576 int key = in.readInt(); 577 long val = in.readLong(); 578 addStartupTimestamp(key, val); 579 } 580 mStartType = in.readInt(); 581 mStartIntent = 582 in.readParcelable(Intent.class.getClassLoader(), android.content.Intent.class); 583 mLaunchMode = in.readInt(); 584 } 585 intern(@ullable String source)586 private static String intern(@Nullable String source) { 587 return source != null ? source.intern() : null; 588 } 589 590 public @NonNull static final Creator<ApplicationStartInfo> CREATOR = 591 new Creator<ApplicationStartInfo>() { 592 @Override 593 public ApplicationStartInfo createFromParcel(Parcel in) { 594 return new ApplicationStartInfo(in); 595 } 596 597 @Override 598 public ApplicationStartInfo[] newArray(int size) { 599 return new ApplicationStartInfo[size]; 600 } 601 }; 602 } 603