ActivityThread.java revision 8290eaba47b99398fbe0bd59138f902bde558ecb
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 static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE; 20import static android.app.servertransaction.ActivityLifecycleItem.ON_DESTROY; 21import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE; 22import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME; 23import static android.app.servertransaction.ActivityLifecycleItem.ON_START; 24import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP; 25import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE; 26import static android.view.Display.INVALID_DISPLAY; 27 28import android.annotation.NonNull; 29import android.annotation.Nullable; 30import android.app.assist.AssistContent; 31import android.app.assist.AssistStructure; 32import android.app.backup.BackupAgent; 33import android.app.servertransaction.ActivityLifecycleItem.LifecycleState; 34import android.app.servertransaction.ActivityResultItem; 35import android.app.servertransaction.ClientTransaction; 36import android.app.servertransaction.PendingTransactionActions; 37import android.app.servertransaction.PendingTransactionActions.StopInfo; 38import android.app.servertransaction.TransactionExecutor; 39import android.content.BroadcastReceiver; 40import android.content.ComponentCallbacks2; 41import android.content.ComponentName; 42import android.content.ContentProvider; 43import android.content.Context; 44import android.content.IContentProvider; 45import android.content.IIntentReceiver; 46import android.content.Intent; 47import android.content.pm.ActivityInfo; 48import android.content.pm.ApplicationInfo; 49import android.content.pm.IPackageManager; 50import android.content.pm.InstrumentationInfo; 51import android.content.pm.PackageInfo; 52import android.content.pm.PackageManager; 53import android.content.pm.PackageManager.NameNotFoundException; 54import android.content.pm.ParceledListSlice; 55import android.content.pm.ProviderInfo; 56import android.content.pm.ServiceInfo; 57import android.content.res.AssetManager; 58import android.content.res.CompatibilityInfo; 59import android.content.res.Configuration; 60import android.content.res.Resources; 61import android.content.res.Resources.Theme; 62import android.database.sqlite.SQLiteDatabase; 63import android.database.sqlite.SQLiteDebug; 64import android.database.sqlite.SQLiteDebug.DbStats; 65import android.graphics.Bitmap; 66import android.graphics.Canvas; 67import android.graphics.ImageDecoder; 68import android.hardware.display.DisplayManagerGlobal; 69import android.net.ConnectivityManager; 70import android.net.IConnectivityManager; 71import android.net.Network; 72import android.net.Proxy; 73import android.net.ProxyInfo; 74import android.net.Uri; 75import android.os.AsyncTask; 76import android.os.Binder; 77import android.os.Build; 78import android.os.Bundle; 79import android.os.Debug; 80import android.os.DropBoxManager; 81import android.os.Environment; 82import android.os.GraphicsEnvironment; 83import android.os.Handler; 84import android.os.HandlerExecutor; 85import android.os.IBinder; 86import android.os.LocaleList; 87import android.os.Looper; 88import android.os.Message; 89import android.os.MessageQueue; 90import android.os.Parcel; 91import android.os.ParcelFileDescriptor; 92import android.os.PersistableBundle; 93import android.os.Process; 94import android.os.RemoteException; 95import android.os.ServiceManager; 96import android.os.StrictMode; 97import android.os.SystemClock; 98import android.os.SystemProperties; 99import android.os.Trace; 100import android.os.UserHandle; 101import android.provider.BlockedNumberContract; 102import android.provider.CalendarContract; 103import android.provider.CallLog; 104import android.provider.ContactsContract; 105import android.provider.Downloads; 106import android.provider.FontsContract; 107import android.provider.Settings; 108import android.renderscript.RenderScriptCacheDir; 109import android.security.NetworkSecurityPolicy; 110import android.security.net.config.NetworkSecurityConfigProvider; 111import android.util.AndroidRuntimeException; 112import android.util.ArrayMap; 113import android.util.DisplayMetrics; 114import android.util.EventLog; 115import android.util.Log; 116import android.util.LogPrinter; 117import android.util.MergedConfiguration; 118import android.util.Pair; 119import android.util.PrintWriterPrinter; 120import android.util.Slog; 121import android.util.SparseIntArray; 122import android.util.SuperNotCalledException; 123import android.util.proto.ProtoOutputStream; 124import android.view.ContextThemeWrapper; 125import android.view.Display; 126import android.view.ThreadedRenderer; 127import android.view.View; 128import android.view.ViewDebug; 129import android.view.ViewManager; 130import android.view.ViewRootImpl; 131import android.view.Window; 132import android.view.WindowManager; 133import android.view.WindowManagerGlobal; 134import android.webkit.WebView; 135 136import com.android.internal.annotations.GuardedBy; 137import com.android.internal.annotations.VisibleForTesting; 138import com.android.internal.app.IVoiceInteractor; 139import com.android.internal.content.ReferrerIntent; 140import com.android.internal.os.BinderInternal; 141import com.android.internal.os.RuntimeInit; 142import com.android.internal.os.SomeArgs; 143import com.android.internal.util.ArrayUtils; 144import com.android.internal.util.FastPrintWriter; 145import com.android.org.conscrypt.OpenSSLSocketImpl; 146import com.android.org.conscrypt.TrustedCertificateStore; 147import com.android.server.am.proto.MemInfoDumpProto; 148 149import dalvik.system.BaseDexClassLoader; 150import dalvik.system.CloseGuard; 151import dalvik.system.VMDebug; 152import dalvik.system.VMRuntime; 153 154import libcore.io.DropBox; 155import libcore.io.EventLogger; 156import libcore.io.IoUtils; 157import libcore.net.event.NetworkEventDispatcher; 158 159import org.apache.harmony.dalvik.ddmc.DdmVmInternal; 160 161import java.io.File; 162import java.io.FileDescriptor; 163import java.io.FileOutputStream; 164import java.io.IOException; 165import java.io.PrintWriter; 166import java.lang.ref.WeakReference; 167import java.lang.reflect.Field; 168import java.lang.reflect.Method; 169import java.net.InetAddress; 170import java.text.DateFormat; 171import java.util.ArrayList; 172import java.util.Arrays; 173import java.util.Iterator; 174import java.util.List; 175import java.util.Locale; 176import java.util.Map; 177import java.util.Objects; 178import java.util.TimeZone; 179import java.util.concurrent.Executor; 180 181final class RemoteServiceException extends AndroidRuntimeException { 182 public RemoteServiceException(String msg) { 183 super(msg); 184 } 185} 186 187/** 188 * This manages the execution of the main thread in an 189 * application process, scheduling and executing activities, 190 * broadcasts, and other operations on it as the activity 191 * manager requests. 192 * 193 * {@hide} 194 */ 195public final class ActivityThread extends ClientTransactionHandler { 196 /** @hide */ 197 public static final String TAG = "ActivityThread"; 198 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565; 199 static final boolean localLOGV = false; 200 static final boolean DEBUG_MESSAGES = false; 201 /** @hide */ 202 public static final boolean DEBUG_BROADCAST = false; 203 private static final boolean DEBUG_RESULTS = false; 204 private static final boolean DEBUG_BACKUP = false; 205 public static final boolean DEBUG_CONFIGURATION = false; 206 private static final boolean DEBUG_SERVICE = false; 207 public static final boolean DEBUG_MEMORY_TRIM = false; 208 private static final boolean DEBUG_PROVIDER = false; 209 public static final boolean DEBUG_ORDER = false; 210 private static final long MIN_TIME_BETWEEN_GCS = 5*1000; 211 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; 212 213 /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */ 214 public static final int SERVICE_DONE_EXECUTING_ANON = 0; 215 /** Type for IActivityManager.serviceDoneExecuting: done with an onStart call */ 216 public static final int SERVICE_DONE_EXECUTING_START = 1; 217 /** Type for IActivityManager.serviceDoneExecuting: done stopping (destroying) service */ 218 public static final int SERVICE_DONE_EXECUTING_STOP = 2; 219 220 // Whether to invoke an activity callback after delivering new configuration. 221 private static final boolean REPORT_TO_ACTIVITY = true; 222 223 // Maximum number of recent tokens to maintain for debugging purposes 224 private static final int MAX_DESTROYED_ACTIVITIES = 10; 225 226 /** 227 * Denotes an invalid sequence number corresponding to a process state change. 228 */ 229 public static final long INVALID_PROC_STATE_SEQ = -1; 230 231 /** 232 * Identifier for the sequence no. associated with this process start. It will be provided 233 * as one of the arguments when the process starts. 234 */ 235 public static final String PROC_START_SEQ_IDENT = "seq="; 236 237 private final Object mNetworkPolicyLock = new Object(); 238 239 /** 240 * Denotes the sequence number of the process state change for which the main thread needs 241 * to block until the network rules are updated for it. 242 * 243 * Value of {@link #INVALID_PROC_STATE_SEQ} indicates there is no need for blocking. 244 */ 245 @GuardedBy("mNetworkPolicyLock") 246 private long mNetworkBlockSeq = INVALID_PROC_STATE_SEQ; 247 248 private ContextImpl mSystemContext; 249 private ContextImpl mSystemUiContext; 250 251 static volatile IPackageManager sPackageManager; 252 253 final ApplicationThread mAppThread = new ApplicationThread(); 254 final Looper mLooper = Looper.myLooper(); 255 final H mH = new H(); 256 final Executor mExecutor = new HandlerExecutor(mH); 257 final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>(); 258 final ArrayList<DestroyedActivityInfo> mRecentDestroyedActivities = new ArrayList<>(); 259 260 // List of new activities (via ActivityRecord.nextIdle) that should 261 // be reported when next we idle. 262 ActivityClientRecord mNewActivities = null; 263 // Number of activities that are currently visible on-screen. 264 int mNumVisibleActivities = 0; 265 ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>(); 266 private int mLastSessionId; 267 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); 268 AppBindData mBoundApplication; 269 Profiler mProfiler; 270 int mCurDefaultDisplayDpi; 271 boolean mDensityCompatMode; 272 Configuration mConfiguration; 273 Configuration mCompatConfiguration; 274 Application mInitialApplication; 275 final ArrayList<Application> mAllApplications 276 = new ArrayList<Application>(); 277 // set of instantiated backup agents, keyed by package name 278 final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>(); 279 /** Reference to singleton {@link ActivityThread} */ 280 private static volatile ActivityThread sCurrentActivityThread; 281 Instrumentation mInstrumentation; 282 String mInstrumentationPackageName = null; 283 String mInstrumentationAppDir = null; 284 String[] mInstrumentationSplitAppDirs = null; 285 String mInstrumentationLibDir = null; 286 String mInstrumentedAppDir = null; 287 String[] mInstrumentedSplitAppDirs = null; 288 String mInstrumentedLibDir = null; 289 boolean mSystemThread = false; 290 boolean mJitEnabled = false; 291 boolean mSomeActivitiesChanged = false; 292 boolean mUpdatingSystemConfig = false; 293 /* package */ boolean mHiddenApiWarningShown = false; 294 295 // These can be accessed by multiple threads; mResourcesManager is the lock. 296 // XXX For now we keep around information about all packages we have 297 // seen, not removing entries from this map. 298 // NOTE: The activity and window managers need to call in to 299 // ActivityThread to do things like update resource configurations, 300 // which means this lock gets held while the activity and window managers 301 // holds their own lock. Thus you MUST NEVER call back into the activity manager 302 // or window manager or anything that depends on them while holding this lock. 303 // These LoadedApk are only valid for the userId that we're running as. 304 @GuardedBy("mResourcesManager") 305 final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<>(); 306 @GuardedBy("mResourcesManager") 307 final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<>(); 308 @GuardedBy("mResourcesManager") 309 final ArrayList<ActivityClientRecord> mRelaunchingActivities = new ArrayList<>(); 310 @GuardedBy("mResourcesManager") 311 Configuration mPendingConfiguration = null; 312 // An executor that performs multi-step transactions. 313 private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this); 314 315 private final ResourcesManager mResourcesManager; 316 317 private static final class ProviderKey { 318 final String authority; 319 final int userId; 320 321 public ProviderKey(String authority, int userId) { 322 this.authority = authority; 323 this.userId = userId; 324 } 325 326 @Override 327 public boolean equals(Object o) { 328 if (o instanceof ProviderKey) { 329 final ProviderKey other = (ProviderKey) o; 330 return Objects.equals(authority, other.authority) && userId == other.userId; 331 } 332 return false; 333 } 334 335 @Override 336 public int hashCode() { 337 return ((authority != null) ? authority.hashCode() : 0) ^ userId; 338 } 339 } 340 341 /** 342 * TODO(b/71506345): Remove this once bug is resolved. 343 */ 344 private static final class DestroyedActivityInfo { 345 private final Integer mToken; 346 private final String mReason; 347 private final long mTime; 348 349 DestroyedActivityInfo(Integer token, String reason) { 350 mToken = token; 351 mReason = reason; 352 mTime = System.currentTimeMillis(); 353 } 354 355 void dump(PrintWriter pw, String prefix) { 356 pw.println(prefix + "[token:" + mToken + " | time:" + mTime + " | reason:" + mReason 357 + "]"); 358 } 359 } 360 361 // The lock of mProviderMap protects the following variables. 362 final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap 363 = new ArrayMap<ProviderKey, ProviderClientRecord>(); 364 final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap 365 = new ArrayMap<IBinder, ProviderRefCount>(); 366 final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders 367 = new ArrayMap<IBinder, ProviderClientRecord>(); 368 final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName 369 = new ArrayMap<ComponentName, ProviderClientRecord>(); 370 371 final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners 372 = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); 373 374 final GcIdler mGcIdler = new GcIdler(); 375 boolean mGcIdlerScheduled = false; 376 377 static volatile Handler sMainThreadHandler; // set once in main() 378 379 Bundle mCoreSettings = null; 380 381 /** Activity client record, used for bookkeeping for the real {@link Activity} instance. */ 382 public static final class ActivityClientRecord { 383 public IBinder token; 384 int ident; 385 Intent intent; 386 String referrer; 387 IVoiceInteractor voiceInteractor; 388 Bundle state; 389 PersistableBundle persistentState; 390 Activity activity; 391 Window window; 392 Activity parent; 393 String embeddedID; 394 Activity.NonConfigurationInstances lastNonConfigurationInstances; 395 // TODO(lifecycler): Use mLifecycleState instead. 396 boolean paused; 397 boolean stopped; 398 boolean hideForNow; 399 Configuration newConfig; 400 Configuration createdConfig; 401 Configuration overrideConfig; 402 // Used for consolidating configs before sending on to Activity. 403 private Configuration tmpConfig = new Configuration(); 404 // Callback used for updating activity override config. 405 ViewRootImpl.ActivityConfigCallback configCallback; 406 ActivityClientRecord nextIdle; 407 408 ProfilerInfo profilerInfo; 409 410 ActivityInfo activityInfo; 411 CompatibilityInfo compatInfo; 412 public LoadedApk packageInfo; 413 414 List<ResultInfo> pendingResults; 415 List<ReferrerIntent> pendingIntents; 416 417 boolean startsNotResumed; 418 public final boolean isForward; 419 int pendingConfigChanges; 420 421 Window mPendingRemoveWindow; 422 WindowManager mPendingRemoveWindowManager; 423 boolean mPreserveWindow; 424 425 @LifecycleState 426 private int mLifecycleState = PRE_ON_CREATE; 427 428 @VisibleForTesting 429 public ActivityClientRecord() { 430 this.isForward = false; 431 init(); 432 } 433 434 public ActivityClientRecord(IBinder token, Intent intent, int ident, 435 ActivityInfo info, Configuration overrideConfig, CompatibilityInfo compatInfo, 436 String referrer, IVoiceInteractor voiceInteractor, Bundle state, 437 PersistableBundle persistentState, List<ResultInfo> pendingResults, 438 List<ReferrerIntent> pendingNewIntents, boolean isForward, 439 ProfilerInfo profilerInfo, ClientTransactionHandler client) { 440 this.token = token; 441 this.ident = ident; 442 this.intent = intent; 443 this.referrer = referrer; 444 this.voiceInteractor = voiceInteractor; 445 this.activityInfo = info; 446 this.compatInfo = compatInfo; 447 this.state = state; 448 this.persistentState = persistentState; 449 this.pendingResults = pendingResults; 450 this.pendingIntents = pendingNewIntents; 451 this.isForward = isForward; 452 this.profilerInfo = profilerInfo; 453 this.overrideConfig = overrideConfig; 454 this.packageInfo = client.getPackageInfoNoCheck(activityInfo.applicationInfo, 455 compatInfo); 456 init(); 457 } 458 459 /** Common initializer for all constructors. */ 460 private void init() { 461 parent = null; 462 embeddedID = null; 463 paused = false; 464 stopped = false; 465 hideForNow = false; 466 nextIdle = null; 467 configCallback = (Configuration overrideConfig, int newDisplayId) -> { 468 if (activity == null) { 469 throw new IllegalStateException( 470 "Received config update for non-existing activity"); 471 } 472 activity.mMainThread.handleActivityConfigurationChanged(token, overrideConfig, 473 newDisplayId); 474 }; 475 } 476 477 /** Get the current lifecycle state. */ 478 public int getLifecycleState() { 479 return mLifecycleState; 480 } 481 482 /** Update the current lifecycle state for internal bookkeeping. */ 483 public void setState(@LifecycleState int newLifecycleState) { 484 mLifecycleState = newLifecycleState; 485 switch (mLifecycleState) { 486 case ON_CREATE: 487 paused = true; 488 stopped = true; 489 break; 490 case ON_START: 491 paused = true; 492 stopped = false; 493 break; 494 case ON_RESUME: 495 paused = false; 496 stopped = false; 497 break; 498 case ON_PAUSE: 499 paused = true; 500 stopped = false; 501 break; 502 case ON_STOP: 503 paused = true; 504 stopped = true; 505 break; 506 } 507 } 508 509 private boolean isPreHoneycomb() { 510 return activity != null && activity.getApplicationInfo().targetSdkVersion 511 < android.os.Build.VERSION_CODES.HONEYCOMB; 512 } 513 514 private boolean isPreP() { 515 return activity != null && activity.getApplicationInfo().targetSdkVersion 516 < android.os.Build.VERSION_CODES.P; 517 } 518 519 public boolean isPersistable() { 520 return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS; 521 } 522 523 public String toString() { 524 ComponentName componentName = intent != null ? intent.getComponent() : null; 525 return "ActivityRecord{" 526 + Integer.toHexString(System.identityHashCode(this)) 527 + " token=" + token + " " + (componentName == null 528 ? "no component name" : componentName.toShortString()) 529 + "}"; 530 } 531 532 public String getStateString() { 533 StringBuilder sb = new StringBuilder(); 534 sb.append("ActivityClientRecord{"); 535 sb.append("paused=").append(paused); 536 sb.append(", stopped=").append(stopped); 537 sb.append(", hideForNow=").append(hideForNow); 538 sb.append(", startsNotResumed=").append(startsNotResumed); 539 sb.append(", isForward=").append(isForward); 540 sb.append(", pendingConfigChanges=").append(pendingConfigChanges); 541 sb.append(", preserveWindow=").append(mPreserveWindow); 542 if (activity != null) { 543 sb.append(", Activity{"); 544 sb.append("resumed=").append(activity.mResumed); 545 sb.append(", stopped=").append(activity.mStopped); 546 sb.append(", finished=").append(activity.isFinishing()); 547 sb.append(", destroyed=").append(activity.isDestroyed()); 548 sb.append(", startedActivity=").append(activity.mStartedActivity); 549 sb.append(", temporaryPause=").append(activity.mTemporaryPause); 550 sb.append(", changingConfigurations=").append(activity.mChangingConfigurations); 551 sb.append("}"); 552 } 553 sb.append("}"); 554 return sb.toString(); 555 } 556 } 557 558 final class ProviderClientRecord { 559 final String[] mNames; 560 final IContentProvider mProvider; 561 final ContentProvider mLocalProvider; 562 final ContentProviderHolder mHolder; 563 564 ProviderClientRecord(String[] names, IContentProvider provider, 565 ContentProvider localProvider, ContentProviderHolder holder) { 566 mNames = names; 567 mProvider = provider; 568 mLocalProvider = localProvider; 569 mHolder = holder; 570 } 571 } 572 573 static final class ReceiverData extends BroadcastReceiver.PendingResult { 574 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras, 575 boolean ordered, boolean sticky, IBinder token, int sendingUser) { 576 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky, 577 token, sendingUser, intent.getFlags()); 578 this.intent = intent; 579 } 580 581 Intent intent; 582 ActivityInfo info; 583 CompatibilityInfo compatInfo; 584 public String toString() { 585 return "ReceiverData{intent=" + intent + " packageName=" + 586 info.packageName + " resultCode=" + getResultCode() 587 + " resultData=" + getResultData() + " resultExtras=" 588 + getResultExtras(false) + "}"; 589 } 590 } 591 592 static final class CreateBackupAgentData { 593 ApplicationInfo appInfo; 594 CompatibilityInfo compatInfo; 595 int backupMode; 596 public String toString() { 597 return "CreateBackupAgentData{appInfo=" + appInfo 598 + " backupAgent=" + appInfo.backupAgentName 599 + " mode=" + backupMode + "}"; 600 } 601 } 602 603 static final class CreateServiceData { 604 IBinder token; 605 ServiceInfo info; 606 CompatibilityInfo compatInfo; 607 Intent intent; 608 public String toString() { 609 return "CreateServiceData{token=" + token + " className=" 610 + info.name + " packageName=" + info.packageName 611 + " intent=" + intent + "}"; 612 } 613 } 614 615 static final class BindServiceData { 616 IBinder token; 617 Intent intent; 618 boolean rebind; 619 public String toString() { 620 return "BindServiceData{token=" + token + " intent=" + intent + "}"; 621 } 622 } 623 624 static final class ServiceArgsData { 625 IBinder token; 626 boolean taskRemoved; 627 int startId; 628 int flags; 629 Intent args; 630 public String toString() { 631 return "ServiceArgsData{token=" + token + " startId=" + startId 632 + " args=" + args + "}"; 633 } 634 } 635 636 static final class AppBindData { 637 LoadedApk info; 638 String processName; 639 ApplicationInfo appInfo; 640 List<ProviderInfo> providers; 641 ComponentName instrumentationName; 642 Bundle instrumentationArgs; 643 IInstrumentationWatcher instrumentationWatcher; 644 IUiAutomationConnection instrumentationUiAutomationConnection; 645 int debugMode; 646 boolean enableBinderTracking; 647 boolean trackAllocation; 648 boolean restrictedBackupMode; 649 boolean persistent; 650 Configuration config; 651 CompatibilityInfo compatInfo; 652 String buildSerial; 653 654 /** Initial values for {@link Profiler}. */ 655 ProfilerInfo initProfilerInfo; 656 657 boolean autofillCompatibilityEnabled; 658 659 public String toString() { 660 return "AppBindData{appInfo=" + appInfo + "}"; 661 } 662 } 663 664 static final class Profiler { 665 String profileFile; 666 ParcelFileDescriptor profileFd; 667 int samplingInterval; 668 boolean autoStopProfiler; 669 boolean streamingOutput; 670 boolean profiling; 671 boolean handlingProfiling; 672 public void setProfiler(ProfilerInfo profilerInfo) { 673 ParcelFileDescriptor fd = profilerInfo.profileFd; 674 if (profiling) { 675 if (fd != null) { 676 try { 677 fd.close(); 678 } catch (IOException e) { 679 // Ignore 680 } 681 } 682 return; 683 } 684 if (profileFd != null) { 685 try { 686 profileFd.close(); 687 } catch (IOException e) { 688 // Ignore 689 } 690 } 691 profileFile = profilerInfo.profileFile; 692 profileFd = fd; 693 samplingInterval = profilerInfo.samplingInterval; 694 autoStopProfiler = profilerInfo.autoStopProfiler; 695 streamingOutput = profilerInfo.streamingOutput; 696 } 697 public void startProfiling() { 698 if (profileFd == null || profiling) { 699 return; 700 } 701 try { 702 int bufferSize = SystemProperties.getInt("debug.traceview-buffer-size-mb", 8); 703 VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(), 704 bufferSize * 1024 * 1024, 0, samplingInterval != 0, samplingInterval, 705 streamingOutput); 706 profiling = true; 707 } catch (RuntimeException e) { 708 Slog.w(TAG, "Profiling failed on path " + profileFile); 709 try { 710 profileFd.close(); 711 profileFd = null; 712 } catch (IOException e2) { 713 Slog.w(TAG, "Failure closing profile fd", e2); 714 } 715 } 716 } 717 public void stopProfiling() { 718 if (profiling) { 719 profiling = false; 720 Debug.stopMethodTracing(); 721 if (profileFd != null) { 722 try { 723 profileFd.close(); 724 } catch (IOException e) { 725 } 726 } 727 profileFd = null; 728 profileFile = null; 729 } 730 } 731 } 732 733 static final class DumpComponentInfo { 734 ParcelFileDescriptor fd; 735 IBinder token; 736 String prefix; 737 String[] args; 738 } 739 740 static final class ContextCleanupInfo { 741 ContextImpl context; 742 String what; 743 String who; 744 } 745 746 static final class DumpHeapData { 747 public boolean managed; 748 public boolean mallocInfo; 749 public boolean runGc; 750 String path; 751 ParcelFileDescriptor fd; 752 } 753 754 static final class UpdateCompatibilityData { 755 String pkg; 756 CompatibilityInfo info; 757 } 758 759 static final class RequestAssistContextExtras { 760 IBinder activityToken; 761 IBinder requestToken; 762 int requestType; 763 int sessionId; 764 int flags; 765 } 766 767 private class ApplicationThread extends IApplicationThread.Stub { 768 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; 769 770 private int mLastProcessState = -1; 771 772 private void updatePendingConfiguration(Configuration config) { 773 synchronized (mResourcesManager) { 774 if (mPendingConfiguration == null || 775 mPendingConfiguration.isOtherSeqNewer(config)) { 776 mPendingConfiguration = config; 777 } 778 } 779 } 780 781 public final void scheduleSleeping(IBinder token, boolean sleeping) { 782 sendMessage(H.SLEEPING, token, sleeping ? 1 : 0); 783 } 784 785 public final void scheduleReceiver(Intent intent, ActivityInfo info, 786 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, 787 boolean sync, int sendingUser, int processState) { 788 updateProcessState(processState, false); 789 ReceiverData r = new ReceiverData(intent, resultCode, data, extras, 790 sync, false, mAppThread.asBinder(), sendingUser); 791 r.info = info; 792 r.compatInfo = compatInfo; 793 sendMessage(H.RECEIVER, r); 794 } 795 796 public final void scheduleCreateBackupAgent(ApplicationInfo app, 797 CompatibilityInfo compatInfo, int backupMode) { 798 CreateBackupAgentData d = new CreateBackupAgentData(); 799 d.appInfo = app; 800 d.compatInfo = compatInfo; 801 d.backupMode = backupMode; 802 803 sendMessage(H.CREATE_BACKUP_AGENT, d); 804 } 805 806 public final void scheduleDestroyBackupAgent(ApplicationInfo app, 807 CompatibilityInfo compatInfo) { 808 CreateBackupAgentData d = new CreateBackupAgentData(); 809 d.appInfo = app; 810 d.compatInfo = compatInfo; 811 812 sendMessage(H.DESTROY_BACKUP_AGENT, d); 813 } 814 815 public final void scheduleCreateService(IBinder token, 816 ServiceInfo info, CompatibilityInfo compatInfo, int processState) { 817 updateProcessState(processState, false); 818 CreateServiceData s = new CreateServiceData(); 819 s.token = token; 820 s.info = info; 821 s.compatInfo = compatInfo; 822 823 sendMessage(H.CREATE_SERVICE, s); 824 } 825 826 public final void scheduleBindService(IBinder token, Intent intent, 827 boolean rebind, int processState) { 828 updateProcessState(processState, false); 829 BindServiceData s = new BindServiceData(); 830 s.token = token; 831 s.intent = intent; 832 s.rebind = rebind; 833 834 if (DEBUG_SERVICE) 835 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" 836 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); 837 sendMessage(H.BIND_SERVICE, s); 838 } 839 840 public final void scheduleUnbindService(IBinder token, Intent intent) { 841 BindServiceData s = new BindServiceData(); 842 s.token = token; 843 s.intent = intent; 844 845 sendMessage(H.UNBIND_SERVICE, s); 846 } 847 848 public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) { 849 List<ServiceStartArgs> list = args.getList(); 850 851 for (int i = 0; i < list.size(); i++) { 852 ServiceStartArgs ssa = list.get(i); 853 ServiceArgsData s = new ServiceArgsData(); 854 s.token = token; 855 s.taskRemoved = ssa.taskRemoved; 856 s.startId = ssa.startId; 857 s.flags = ssa.flags; 858 s.args = ssa.args; 859 860 sendMessage(H.SERVICE_ARGS, s); 861 } 862 } 863 864 public final void scheduleStopService(IBinder token) { 865 sendMessage(H.STOP_SERVICE, token); 866 } 867 868 public final void bindApplication(String processName, ApplicationInfo appInfo, 869 List<ProviderInfo> providers, ComponentName instrumentationName, 870 ProfilerInfo profilerInfo, Bundle instrumentationArgs, 871 IInstrumentationWatcher instrumentationWatcher, 872 IUiAutomationConnection instrumentationUiConnection, int debugMode, 873 boolean enableBinderTracking, boolean trackAllocation, 874 boolean isRestrictedBackupMode, boolean persistent, Configuration config, 875 CompatibilityInfo compatInfo, Map services, Bundle coreSettings, 876 String buildSerial, boolean autofillCompatibilityEnabled) { 877 878 if (services != null) { 879 // Setup the service cache in the ServiceManager 880 ServiceManager.initServiceCache(services); 881 } 882 883 setCoreSettings(coreSettings); 884 885 AppBindData data = new AppBindData(); 886 data.processName = processName; 887 data.appInfo = appInfo; 888 data.providers = providers; 889 data.instrumentationName = instrumentationName; 890 data.instrumentationArgs = instrumentationArgs; 891 data.instrumentationWatcher = instrumentationWatcher; 892 data.instrumentationUiAutomationConnection = instrumentationUiConnection; 893 data.debugMode = debugMode; 894 data.enableBinderTracking = enableBinderTracking; 895 data.trackAllocation = trackAllocation; 896 data.restrictedBackupMode = isRestrictedBackupMode; 897 data.persistent = persistent; 898 data.config = config; 899 data.compatInfo = compatInfo; 900 data.initProfilerInfo = profilerInfo; 901 data.buildSerial = buildSerial; 902 data.autofillCompatibilityEnabled = autofillCompatibilityEnabled; 903 sendMessage(H.BIND_APPLICATION, data); 904 } 905 906 public final void runIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) { 907 SomeArgs args = SomeArgs.obtain(); 908 args.arg1 = entryPoint; 909 args.arg2 = entryPointArgs; 910 sendMessage(H.RUN_ISOLATED_ENTRY_POINT, args); 911 } 912 913 public final void scheduleExit() { 914 sendMessage(H.EXIT_APPLICATION, null); 915 } 916 917 public final void scheduleSuicide() { 918 sendMessage(H.SUICIDE, null); 919 } 920 921 public void scheduleApplicationInfoChanged(ApplicationInfo ai) { 922 sendMessage(H.APPLICATION_INFO_CHANGED, ai); 923 } 924 925 public void updateTimeZone() { 926 TimeZone.setDefault(null); 927 } 928 929 public void clearDnsCache() { 930 // a non-standard API to get this to libcore 931 InetAddress.clearDnsCache(); 932 // Allow libcore to perform the necessary actions as it sees fit upon a network 933 // configuration change. 934 NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged(); 935 } 936 937 public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) { 938 final ConnectivityManager cm = ConnectivityManager.from(getSystemContext()); 939 final Network network = cm.getBoundNetworkForProcess(); 940 if (network != null) { 941 Proxy.setHttpProxySystemProperty(cm.getDefaultProxy()); 942 } else { 943 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl); 944 } 945 } 946 947 public void processInBackground() { 948 mH.removeMessages(H.GC_WHEN_IDLE); 949 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE)); 950 } 951 952 public void dumpService(ParcelFileDescriptor pfd, IBinder servicetoken, String[] args) { 953 DumpComponentInfo data = new DumpComponentInfo(); 954 try { 955 data.fd = pfd.dup(); 956 data.token = servicetoken; 957 data.args = args; 958 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/); 959 } catch (IOException e) { 960 Slog.w(TAG, "dumpService failed", e); 961 } finally { 962 IoUtils.closeQuietly(pfd); 963 } 964 } 965 966 // This function exists to make sure all receiver dispatching is 967 // correctly ordered, since these are one-way calls and the binder driver 968 // applies transaction ordering per object for such calls. 969 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, 970 int resultCode, String dataStr, Bundle extras, boolean ordered, 971 boolean sticky, int sendingUser, int processState) throws RemoteException { 972 updateProcessState(processState, false); 973 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, 974 sticky, sendingUser); 975 } 976 977 @Override 978 public void scheduleLowMemory() { 979 sendMessage(H.LOW_MEMORY, null); 980 } 981 982 @Override 983 public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 984 sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType); 985 } 986 987 @Override 988 public void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, String path, 989 ParcelFileDescriptor fd) { 990 DumpHeapData dhd = new DumpHeapData(); 991 dhd.managed = managed; 992 dhd.mallocInfo = mallocInfo; 993 dhd.runGc = runGc; 994 dhd.path = path; 995 dhd.fd = fd; 996 sendMessage(H.DUMP_HEAP, dhd, 0, 0, true /*async*/); 997 } 998 999 public void attachAgent(String agent) { 1000 sendMessage(H.ATTACH_AGENT, agent); 1001 } 1002 1003 public void setSchedulingGroup(int group) { 1004 // Note: do this immediately, since going into the foreground 1005 // should happen regardless of what pending work we have to do 1006 // and the activity manager will wait for us to report back that 1007 // we are done before sending us to the background. 1008 try { 1009 Process.setProcessGroup(Process.myPid(), group); 1010 } catch (Exception e) { 1011 Slog.w(TAG, "Failed setting process group to " + group, e); 1012 } 1013 } 1014 1015 public void dispatchPackageBroadcast(int cmd, String[] packages) { 1016 sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd); 1017 } 1018 1019 public void scheduleCrash(String msg) { 1020 sendMessage(H.SCHEDULE_CRASH, msg); 1021 } 1022 1023 public void dumpActivity(ParcelFileDescriptor pfd, IBinder activitytoken, 1024 String prefix, String[] args) { 1025 DumpComponentInfo data = new DumpComponentInfo(); 1026 try { 1027 data.fd = pfd.dup(); 1028 data.token = activitytoken; 1029 data.prefix = prefix; 1030 data.args = args; 1031 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/); 1032 } catch (IOException e) { 1033 Slog.w(TAG, "dumpActivity failed", e); 1034 } finally { 1035 IoUtils.closeQuietly(pfd); 1036 } 1037 } 1038 1039 public void dumpProvider(ParcelFileDescriptor pfd, IBinder providertoken, 1040 String[] args) { 1041 DumpComponentInfo data = new DumpComponentInfo(); 1042 try { 1043 data.fd = pfd.dup(); 1044 data.token = providertoken; 1045 data.args = args; 1046 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/); 1047 } catch (IOException e) { 1048 Slog.w(TAG, "dumpProvider failed", e); 1049 } finally { 1050 IoUtils.closeQuietly(pfd); 1051 } 1052 } 1053 1054 @Override 1055 public void dumpMemInfo(ParcelFileDescriptor pfd, Debug.MemoryInfo mem, boolean checkin, 1056 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, 1057 boolean dumpUnreachable, String[] args) { 1058 FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor()); 1059 PrintWriter pw = new FastPrintWriter(fout); 1060 try { 1061 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable); 1062 } finally { 1063 pw.flush(); 1064 IoUtils.closeQuietly(pfd); 1065 } 1066 } 1067 1068 private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 1069 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable) { 1070 long nativeMax = Debug.getNativeHeapSize() / 1024; 1071 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; 1072 long nativeFree = Debug.getNativeHeapFreeSize() / 1024; 1073 1074 Runtime runtime = Runtime.getRuntime(); 1075 runtime.gc(); // Do GC since countInstancesOfClass counts unreachable objects. 1076 long dalvikMax = runtime.totalMemory() / 1024; 1077 long dalvikFree = runtime.freeMemory() / 1024; 1078 long dalvikAllocated = dalvikMax - dalvikFree; 1079 1080 Class[] classesToCount = new Class[] { 1081 ContextImpl.class, 1082 Activity.class, 1083 WebView.class, 1084 OpenSSLSocketImpl.class 1085 }; 1086 long[] instanceCounts = VMDebug.countInstancesOfClasses(classesToCount, true); 1087 long appContextInstanceCount = instanceCounts[0]; 1088 long activityInstanceCount = instanceCounts[1]; 1089 long webviewInstanceCount = instanceCounts[2]; 1090 long openSslSocketCount = instanceCounts[3]; 1091 1092 long viewInstanceCount = ViewDebug.getViewInstanceCount(); 1093 long viewRootInstanceCount = ViewDebug.getViewRootImplCount(); 1094 int globalAssetCount = AssetManager.getGlobalAssetCount(); 1095 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount(); 1096 int binderLocalObjectCount = Debug.getBinderLocalObjectCount(); 1097 int binderProxyObjectCount = Debug.getBinderProxyObjectCount(); 1098 int binderDeathObjectCount = Debug.getBinderDeathObjectCount(); 1099 long parcelSize = Parcel.getGlobalAllocSize(); 1100 long parcelCount = Parcel.getGlobalAllocCount(); 1101 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo(); 1102 1103 dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, 1104 Process.myPid(), 1105 (mBoundApplication != null) ? mBoundApplication.processName : "unknown", 1106 nativeMax, nativeAllocated, nativeFree, 1107 dalvikMax, dalvikAllocated, dalvikFree); 1108 1109 if (checkin) { 1110 // NOTE: if you change anything significant below, also consider changing 1111 // ACTIVITY_THREAD_CHECKIN_VERSION. 1112 1113 // Object counts 1114 pw.print(viewInstanceCount); pw.print(','); 1115 pw.print(viewRootInstanceCount); pw.print(','); 1116 pw.print(appContextInstanceCount); pw.print(','); 1117 pw.print(activityInstanceCount); pw.print(','); 1118 1119 pw.print(globalAssetCount); pw.print(','); 1120 pw.print(globalAssetManagerCount); pw.print(','); 1121 pw.print(binderLocalObjectCount); pw.print(','); 1122 pw.print(binderProxyObjectCount); pw.print(','); 1123 1124 pw.print(binderDeathObjectCount); pw.print(','); 1125 pw.print(openSslSocketCount); pw.print(','); 1126 1127 // SQL 1128 pw.print(stats.memoryUsed / 1024); pw.print(','); 1129 pw.print(stats.memoryUsed / 1024); pw.print(','); 1130 pw.print(stats.pageCacheOverflow / 1024); pw.print(','); 1131 pw.print(stats.largestMemAlloc / 1024); 1132 for (int i = 0; i < stats.dbStats.size(); i++) { 1133 DbStats dbStats = stats.dbStats.get(i); 1134 pw.print(','); pw.print(dbStats.dbName); 1135 pw.print(','); pw.print(dbStats.pageSize); 1136 pw.print(','); pw.print(dbStats.dbSize); 1137 pw.print(','); pw.print(dbStats.lookaside); 1138 pw.print(','); pw.print(dbStats.cache); 1139 pw.print(','); pw.print(dbStats.cache); 1140 } 1141 pw.println(); 1142 1143 return; 1144 } 1145 1146 pw.println(" "); 1147 pw.println(" Objects"); 1148 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:", 1149 viewRootInstanceCount); 1150 1151 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount, 1152 "Activities:", activityInstanceCount); 1153 1154 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount, 1155 "AssetManagers:", globalAssetManagerCount); 1156 1157 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount, 1158 "Proxy Binders:", binderProxyObjectCount); 1159 printRow(pw, TWO_COUNT_COLUMNS, "Parcel memory:", parcelSize/1024, 1160 "Parcel count:", parcelCount); 1161 printRow(pw, TWO_COUNT_COLUMNS, "Death Recipients:", binderDeathObjectCount, 1162 "OpenSSL Sockets:", openSslSocketCount); 1163 printRow(pw, ONE_COUNT_COLUMN, "WebViews:", webviewInstanceCount); 1164 1165 // SQLite mem info 1166 pw.println(" "); 1167 pw.println(" SQL"); 1168 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024); 1169 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:", 1170 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024); 1171 pw.println(" "); 1172 int N = stats.dbStats.size(); 1173 if (N > 0) { 1174 pw.println(" DATABASES"); 1175 printRow(pw, DB_INFO_FORMAT, "pgsz", "dbsz", "Lookaside(b)", "cache", 1176 "Dbname"); 1177 for (int i = 0; i < N; i++) { 1178 DbStats dbStats = stats.dbStats.get(i); 1179 printRow(pw, DB_INFO_FORMAT, 1180 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ", 1181 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ", 1182 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ", 1183 dbStats.cache, dbStats.dbName); 1184 } 1185 } 1186 1187 // Asset details. 1188 String assetAlloc = AssetManager.getAssetAllocations(); 1189 if (assetAlloc != null) { 1190 pw.println(" "); 1191 pw.println(" Asset Allocations"); 1192 pw.print(assetAlloc); 1193 } 1194 1195 // Unreachable native memory 1196 if (dumpUnreachable) { 1197 boolean showContents = ((mBoundApplication != null) 1198 && ((mBoundApplication.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0)) 1199 || android.os.Build.IS_DEBUGGABLE; 1200 pw.println(" "); 1201 pw.println(" Unreachable memory"); 1202 pw.print(Debug.getUnreachableMemory(100, showContents)); 1203 } 1204 } 1205 1206 @Override 1207 public void dumpMemInfoProto(ParcelFileDescriptor pfd, Debug.MemoryInfo mem, 1208 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, 1209 boolean dumpUnreachable, String[] args) { 1210 ProtoOutputStream proto = new ProtoOutputStream(pfd.getFileDescriptor()); 1211 try { 1212 dumpMemInfo(proto, mem, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable); 1213 } finally { 1214 proto.flush(); 1215 IoUtils.closeQuietly(pfd); 1216 } 1217 } 1218 1219 private void dumpMemInfo(ProtoOutputStream proto, Debug.MemoryInfo memInfo, 1220 boolean dumpFullInfo, boolean dumpDalvik, 1221 boolean dumpSummaryOnly, boolean dumpUnreachable) { 1222 long nativeMax = Debug.getNativeHeapSize() / 1024; 1223 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; 1224 long nativeFree = Debug.getNativeHeapFreeSize() / 1024; 1225 1226 Runtime runtime = Runtime.getRuntime(); 1227 runtime.gc(); // Do GC since countInstancesOfClass counts unreachable objects. 1228 long dalvikMax = runtime.totalMemory() / 1024; 1229 long dalvikFree = runtime.freeMemory() / 1024; 1230 long dalvikAllocated = dalvikMax - dalvikFree; 1231 1232 Class[] classesToCount = new Class[] { 1233 ContextImpl.class, 1234 Activity.class, 1235 WebView.class, 1236 OpenSSLSocketImpl.class 1237 }; 1238 long[] instanceCounts = VMDebug.countInstancesOfClasses(classesToCount, true); 1239 long appContextInstanceCount = instanceCounts[0]; 1240 long activityInstanceCount = instanceCounts[1]; 1241 long webviewInstanceCount = instanceCounts[2]; 1242 long openSslSocketCount = instanceCounts[3]; 1243 1244 long viewInstanceCount = ViewDebug.getViewInstanceCount(); 1245 long viewRootInstanceCount = ViewDebug.getViewRootImplCount(); 1246 int globalAssetCount = AssetManager.getGlobalAssetCount(); 1247 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount(); 1248 int binderLocalObjectCount = Debug.getBinderLocalObjectCount(); 1249 int binderProxyObjectCount = Debug.getBinderProxyObjectCount(); 1250 int binderDeathObjectCount = Debug.getBinderDeathObjectCount(); 1251 long parcelSize = Parcel.getGlobalAllocSize(); 1252 long parcelCount = Parcel.getGlobalAllocCount(); 1253 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo(); 1254 1255 final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY); 1256 proto.write(MemInfoDumpProto.ProcessMemory.PID, Process.myPid()); 1257 proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, 1258 (mBoundApplication != null) ? mBoundApplication.processName : "unknown"); 1259 dumpMemInfoTable(proto, memInfo, dumpDalvik, dumpSummaryOnly, 1260 nativeMax, nativeAllocated, nativeFree, 1261 dalvikMax, dalvikAllocated, dalvikFree); 1262 proto.end(mToken); 1263 1264 final long oToken = proto.start(MemInfoDumpProto.AppData.OBJECTS); 1265 proto.write(MemInfoDumpProto.AppData.ObjectStats.VIEW_INSTANCE_COUNT, 1266 viewInstanceCount); 1267 proto.write(MemInfoDumpProto.AppData.ObjectStats.VIEW_ROOT_INSTANCE_COUNT, 1268 viewRootInstanceCount); 1269 proto.write(MemInfoDumpProto.AppData.ObjectStats.APP_CONTEXT_INSTANCE_COUNT, 1270 appContextInstanceCount); 1271 proto.write(MemInfoDumpProto.AppData.ObjectStats.ACTIVITY_INSTANCE_COUNT, 1272 activityInstanceCount); 1273 proto.write(MemInfoDumpProto.AppData.ObjectStats.GLOBAL_ASSET_COUNT, 1274 globalAssetCount); 1275 proto.write(MemInfoDumpProto.AppData.ObjectStats.GLOBAL_ASSET_MANAGER_COUNT, 1276 globalAssetManagerCount); 1277 proto.write(MemInfoDumpProto.AppData.ObjectStats.LOCAL_BINDER_OBJECT_COUNT, 1278 binderLocalObjectCount); 1279 proto.write(MemInfoDumpProto.AppData.ObjectStats.PROXY_BINDER_OBJECT_COUNT, 1280 binderProxyObjectCount); 1281 proto.write(MemInfoDumpProto.AppData.ObjectStats.PARCEL_MEMORY_KB, 1282 parcelSize / 1024); 1283 proto.write(MemInfoDumpProto.AppData.ObjectStats.PARCEL_COUNT, parcelCount); 1284 proto.write(MemInfoDumpProto.AppData.ObjectStats.BINDER_OBJECT_DEATH_COUNT, 1285 binderDeathObjectCount); 1286 proto.write(MemInfoDumpProto.AppData.ObjectStats.OPEN_SSL_SOCKET_COUNT, 1287 openSslSocketCount); 1288 proto.write(MemInfoDumpProto.AppData.ObjectStats.WEBVIEW_INSTANCE_COUNT, 1289 webviewInstanceCount); 1290 proto.end(oToken); 1291 1292 // SQLite mem info 1293 final long sToken = proto.start(MemInfoDumpProto.AppData.SQL); 1294 proto.write(MemInfoDumpProto.AppData.SqlStats.MEMORY_USED_KB, 1295 stats.memoryUsed / 1024); 1296 proto.write(MemInfoDumpProto.AppData.SqlStats.PAGECACHE_OVERFLOW_KB, 1297 stats.pageCacheOverflow / 1024); 1298 proto.write(MemInfoDumpProto.AppData.SqlStats.MALLOC_SIZE_KB, 1299 stats.largestMemAlloc / 1024); 1300 int n = stats.dbStats.size(); 1301 for (int i = 0; i < n; i++) { 1302 DbStats dbStats = stats.dbStats.get(i); 1303 1304 final long dToken = proto.start(MemInfoDumpProto.AppData.SqlStats.DATABASES); 1305 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.NAME, dbStats.dbName); 1306 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.PAGE_SIZE, dbStats.pageSize); 1307 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.DB_SIZE, dbStats.dbSize); 1308 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.LOOKASIDE_B, 1309 dbStats.lookaside); 1310 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.CACHE, dbStats.cache); 1311 proto.end(dToken); 1312 } 1313 proto.end(sToken); 1314 1315 // Asset details. 1316 String assetAlloc = AssetManager.getAssetAllocations(); 1317 if (assetAlloc != null) { 1318 proto.write(MemInfoDumpProto.AppData.ASSET_ALLOCATIONS, assetAlloc); 1319 } 1320 1321 // Unreachable native memory 1322 if (dumpUnreachable) { 1323 int flags = mBoundApplication == null ? 0 : mBoundApplication.appInfo.flags; 1324 boolean showContents = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0 1325 || android.os.Build.IS_DEBUGGABLE; 1326 proto.write(MemInfoDumpProto.AppData.UNREACHABLE_MEMORY, 1327 Debug.getUnreachableMemory(100, showContents)); 1328 } 1329 } 1330 1331 @Override 1332 public void dumpGfxInfo(ParcelFileDescriptor pfd, String[] args) { 1333 nDumpGraphicsInfo(pfd.getFileDescriptor()); 1334 WindowManagerGlobal.getInstance().dumpGfxInfo(pfd.getFileDescriptor(), args); 1335 IoUtils.closeQuietly(pfd); 1336 } 1337 1338 private void dumpDatabaseInfo(ParcelFileDescriptor pfd, String[] args) { 1339 PrintWriter pw = new FastPrintWriter( 1340 new FileOutputStream(pfd.getFileDescriptor())); 1341 PrintWriterPrinter printer = new PrintWriterPrinter(pw); 1342 SQLiteDebug.dump(printer, args); 1343 pw.flush(); 1344 } 1345 1346 @Override 1347 public void dumpDbInfo(final ParcelFileDescriptor pfd, final String[] args) { 1348 if (mSystemThread) { 1349 // Ensure this invocation is asynchronous to prevent writer waiting if buffer cannot 1350 // be consumed. But it must duplicate the file descriptor first, since caller might 1351 // be closing it. 1352 final ParcelFileDescriptor dup; 1353 try { 1354 dup = pfd.dup(); 1355 } catch (IOException e) { 1356 Log.w(TAG, "Could not dup FD " + pfd.getFileDescriptor().getInt$()); 1357 return; 1358 } finally { 1359 IoUtils.closeQuietly(pfd); 1360 } 1361 1362 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() { 1363 @Override 1364 public void run() { 1365 try { 1366 dumpDatabaseInfo(dup, args); 1367 } finally { 1368 IoUtils.closeQuietly(dup); 1369 } 1370 } 1371 }); 1372 } else { 1373 dumpDatabaseInfo(pfd, args); 1374 IoUtils.closeQuietly(pfd); 1375 } 1376 } 1377 1378 @Override 1379 public void unstableProviderDied(IBinder provider) { 1380 sendMessage(H.UNSTABLE_PROVIDER_DIED, provider); 1381 } 1382 1383 @Override 1384 public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, 1385 int requestType, int sessionId, int flags) { 1386 RequestAssistContextExtras cmd = new RequestAssistContextExtras(); 1387 cmd.activityToken = activityToken; 1388 cmd.requestToken = requestToken; 1389 cmd.requestType = requestType; 1390 cmd.sessionId = sessionId; 1391 cmd.flags = flags; 1392 sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd); 1393 } 1394 1395 public void setCoreSettings(Bundle coreSettings) { 1396 sendMessage(H.SET_CORE_SETTINGS, coreSettings); 1397 } 1398 1399 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) { 1400 UpdateCompatibilityData ucd = new UpdateCompatibilityData(); 1401 ucd.pkg = pkg; 1402 ucd.info = info; 1403 sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd); 1404 } 1405 1406 public void scheduleTrimMemory(int level) { 1407 sendMessage(H.TRIM_MEMORY, null, level); 1408 } 1409 1410 public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 1411 sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0); 1412 } 1413 1414 public void scheduleOnNewActivityOptions(IBinder token, Bundle options) { 1415 sendMessage(H.ON_NEW_ACTIVITY_OPTIONS, 1416 new Pair<IBinder, ActivityOptions>(token, ActivityOptions.fromBundle(options))); 1417 } 1418 1419 public void setProcessState(int state) { 1420 updateProcessState(state, true); 1421 } 1422 1423 public void updateProcessState(int processState, boolean fromIpc) { 1424 synchronized (this) { 1425 if (mLastProcessState != processState) { 1426 mLastProcessState = processState; 1427 // Update Dalvik state based on ActivityManager.PROCESS_STATE_* constants. 1428 final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0; 1429 final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1; 1430 int dalvikProcessState = DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE; 1431 // TODO: Tune this since things like gmail sync are important background but not jank perceptible. 1432 if (processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 1433 dalvikProcessState = DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE; 1434 } 1435 VMRuntime.getRuntime().updateProcessState(dalvikProcessState); 1436 if (false) { 1437 Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState 1438 + (fromIpc ? " (from ipc": "")); 1439 } 1440 } 1441 } 1442 } 1443 1444 /** 1445 * Updates {@link #mNetworkBlockSeq}. This is used by ActivityManagerService to inform 1446 * the main thread that it needs to wait for the network rules to get updated before 1447 * launching an activity. 1448 */ 1449 @Override 1450 public void setNetworkBlockSeq(long procStateSeq) { 1451 synchronized (mNetworkPolicyLock) { 1452 mNetworkBlockSeq = procStateSeq; 1453 } 1454 } 1455 1456 @Override 1457 public void scheduleInstallProvider(ProviderInfo provider) { 1458 sendMessage(H.INSTALL_PROVIDER, provider); 1459 } 1460 1461 @Override 1462 public final void updateTimePrefs(int timeFormatPreference) { 1463 final Boolean timeFormatPreferenceBool; 1464 // For convenience we are using the Intent extra values. 1465 if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR) { 1466 timeFormatPreferenceBool = Boolean.FALSE; 1467 } else if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR) { 1468 timeFormatPreferenceBool = Boolean.TRUE; 1469 } else { 1470 // timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT 1471 // (or unknown). 1472 timeFormatPreferenceBool = null; 1473 } 1474 DateFormat.set24HourTimePref(timeFormatPreferenceBool); 1475 } 1476 1477 @Override 1478 public void scheduleEnterAnimationComplete(IBinder token) { 1479 sendMessage(H.ENTER_ANIMATION_COMPLETE, token); 1480 } 1481 1482 @Override 1483 public void notifyCleartextNetwork(byte[] firstPacket) { 1484 if (StrictMode.vmCleartextNetworkEnabled()) { 1485 StrictMode.onCleartextNetworkDetected(firstPacket); 1486 } 1487 } 1488 1489 @Override 1490 public void startBinderTracking() { 1491 sendMessage(H.START_BINDER_TRACKING, null); 1492 } 1493 1494 @Override 1495 public void stopBinderTrackingAndDump(ParcelFileDescriptor pfd) { 1496 try { 1497 sendMessage(H.STOP_BINDER_TRACKING_AND_DUMP, pfd.dup()); 1498 } catch (IOException e) { 1499 } finally { 1500 IoUtils.closeQuietly(pfd); 1501 } 1502 } 1503 1504 @Override 1505 public void scheduleLocalVoiceInteractionStarted(IBinder token, 1506 IVoiceInteractor voiceInteractor) throws RemoteException { 1507 SomeArgs args = SomeArgs.obtain(); 1508 args.arg1 = token; 1509 args.arg2 = voiceInteractor; 1510 sendMessage(H.LOCAL_VOICE_INTERACTION_STARTED, args); 1511 } 1512 1513 @Override 1514 public void handleTrustStorageUpdate() { 1515 NetworkSecurityPolicy.getInstance().handleTrustStorageUpdate(); 1516 } 1517 1518 @Override 1519 public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { 1520 ActivityThread.this.scheduleTransaction(transaction); 1521 } 1522 } 1523 1524 @Override 1525 public void updatePendingConfiguration(Configuration config) { 1526 mAppThread.updatePendingConfiguration(config); 1527 } 1528 1529 @Override 1530 public void updateProcessState(int processState, boolean fromIpc) { 1531 mAppThread.updateProcessState(processState, fromIpc); 1532 } 1533 1534 class H extends Handler { 1535 public static final int BIND_APPLICATION = 110; 1536 public static final int EXIT_APPLICATION = 111; 1537 public static final int RECEIVER = 113; 1538 public static final int CREATE_SERVICE = 114; 1539 public static final int SERVICE_ARGS = 115; 1540 public static final int STOP_SERVICE = 116; 1541 1542 public static final int CONFIGURATION_CHANGED = 118; 1543 public static final int CLEAN_UP_CONTEXT = 119; 1544 public static final int GC_WHEN_IDLE = 120; 1545 public static final int BIND_SERVICE = 121; 1546 public static final int UNBIND_SERVICE = 122; 1547 public static final int DUMP_SERVICE = 123; 1548 public static final int LOW_MEMORY = 124; 1549 public static final int PROFILER_CONTROL = 127; 1550 public static final int CREATE_BACKUP_AGENT = 128; 1551 public static final int DESTROY_BACKUP_AGENT = 129; 1552 public static final int SUICIDE = 130; 1553 public static final int REMOVE_PROVIDER = 131; 1554 public static final int ENABLE_JIT = 132; 1555 public static final int DISPATCH_PACKAGE_BROADCAST = 133; 1556 public static final int SCHEDULE_CRASH = 134; 1557 public static final int DUMP_HEAP = 135; 1558 public static final int DUMP_ACTIVITY = 136; 1559 public static final int SLEEPING = 137; 1560 public static final int SET_CORE_SETTINGS = 138; 1561 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139; 1562 public static final int TRIM_MEMORY = 140; 1563 public static final int DUMP_PROVIDER = 141; 1564 public static final int UNSTABLE_PROVIDER_DIED = 142; 1565 public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143; 1566 public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144; 1567 public static final int INSTALL_PROVIDER = 145; 1568 public static final int ON_NEW_ACTIVITY_OPTIONS = 146; 1569 public static final int ENTER_ANIMATION_COMPLETE = 149; 1570 public static final int START_BINDER_TRACKING = 150; 1571 public static final int STOP_BINDER_TRACKING_AND_DUMP = 151; 1572 public static final int LOCAL_VOICE_INTERACTION_STARTED = 154; 1573 public static final int ATTACH_AGENT = 155; 1574 public static final int APPLICATION_INFO_CHANGED = 156; 1575 public static final int RUN_ISOLATED_ENTRY_POINT = 158; 1576 public static final int EXECUTE_TRANSACTION = 159; 1577 1578 String codeToString(int code) { 1579 if (DEBUG_MESSAGES) { 1580 switch (code) { 1581 case BIND_APPLICATION: return "BIND_APPLICATION"; 1582 case EXIT_APPLICATION: return "EXIT_APPLICATION"; 1583 case RECEIVER: return "RECEIVER"; 1584 case CREATE_SERVICE: return "CREATE_SERVICE"; 1585 case SERVICE_ARGS: return "SERVICE_ARGS"; 1586 case STOP_SERVICE: return "STOP_SERVICE"; 1587 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED"; 1588 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT"; 1589 case GC_WHEN_IDLE: return "GC_WHEN_IDLE"; 1590 case BIND_SERVICE: return "BIND_SERVICE"; 1591 case UNBIND_SERVICE: return "UNBIND_SERVICE"; 1592 case DUMP_SERVICE: return "DUMP_SERVICE"; 1593 case LOW_MEMORY: return "LOW_MEMORY"; 1594 case PROFILER_CONTROL: return "PROFILER_CONTROL"; 1595 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT"; 1596 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT"; 1597 case SUICIDE: return "SUICIDE"; 1598 case REMOVE_PROVIDER: return "REMOVE_PROVIDER"; 1599 case ENABLE_JIT: return "ENABLE_JIT"; 1600 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST"; 1601 case SCHEDULE_CRASH: return "SCHEDULE_CRASH"; 1602 case DUMP_HEAP: return "DUMP_HEAP"; 1603 case DUMP_ACTIVITY: return "DUMP_ACTIVITY"; 1604 case SLEEPING: return "SLEEPING"; 1605 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS"; 1606 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO"; 1607 case TRIM_MEMORY: return "TRIM_MEMORY"; 1608 case DUMP_PROVIDER: return "DUMP_PROVIDER"; 1609 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED"; 1610 case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS"; 1611 case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE"; 1612 case INSTALL_PROVIDER: return "INSTALL_PROVIDER"; 1613 case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS"; 1614 case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE"; 1615 case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED"; 1616 case ATTACH_AGENT: return "ATTACH_AGENT"; 1617 case APPLICATION_INFO_CHANGED: return "APPLICATION_INFO_CHANGED"; 1618 case RUN_ISOLATED_ENTRY_POINT: return "RUN_ISOLATED_ENTRY_POINT"; 1619 case EXECUTE_TRANSACTION: return "EXECUTE_TRANSACTION"; 1620 } 1621 } 1622 return Integer.toString(code); 1623 } 1624 public void handleMessage(Message msg) { 1625 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 1626 switch (msg.what) { 1627 case BIND_APPLICATION: 1628 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); 1629 AppBindData data = (AppBindData)msg.obj; 1630 handleBindApplication(data); 1631 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1632 break; 1633 case EXIT_APPLICATION: 1634 if (mInitialApplication != null) { 1635 mInitialApplication.onTerminate(); 1636 } 1637 Looper.myLooper().quit(); 1638 break; 1639 case RECEIVER: 1640 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp"); 1641 handleReceiver((ReceiverData)msg.obj); 1642 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1643 break; 1644 case CREATE_SERVICE: 1645 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj))); 1646 handleCreateService((CreateServiceData)msg.obj); 1647 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1648 break; 1649 case BIND_SERVICE: 1650 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind"); 1651 handleBindService((BindServiceData)msg.obj); 1652 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1653 break; 1654 case UNBIND_SERVICE: 1655 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind"); 1656 handleUnbindService((BindServiceData)msg.obj); 1657 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1658 break; 1659 case SERVICE_ARGS: 1660 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj))); 1661 handleServiceArgs((ServiceArgsData)msg.obj); 1662 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1663 break; 1664 case STOP_SERVICE: 1665 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop"); 1666 handleStopService((IBinder)msg.obj); 1667 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1668 break; 1669 case CONFIGURATION_CHANGED: 1670 handleConfigurationChanged((Configuration) msg.obj); 1671 break; 1672 case CLEAN_UP_CONTEXT: 1673 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj; 1674 cci.context.performFinalCleanup(cci.who, cci.what); 1675 break; 1676 case GC_WHEN_IDLE: 1677 scheduleGcIdler(); 1678 break; 1679 case DUMP_SERVICE: 1680 handleDumpService((DumpComponentInfo)msg.obj); 1681 break; 1682 case LOW_MEMORY: 1683 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory"); 1684 handleLowMemory(); 1685 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1686 break; 1687 case PROFILER_CONTROL: 1688 handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2); 1689 break; 1690 case CREATE_BACKUP_AGENT: 1691 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent"); 1692 handleCreateBackupAgent((CreateBackupAgentData)msg.obj); 1693 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1694 break; 1695 case DESTROY_BACKUP_AGENT: 1696 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent"); 1697 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj); 1698 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1699 break; 1700 case SUICIDE: 1701 Process.killProcess(Process.myPid()); 1702 break; 1703 case REMOVE_PROVIDER: 1704 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove"); 1705 completeRemoveProvider((ProviderRefCount)msg.obj); 1706 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1707 break; 1708 case ENABLE_JIT: 1709 ensureJitEnabled(); 1710 break; 1711 case DISPATCH_PACKAGE_BROADCAST: 1712 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage"); 1713 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj); 1714 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1715 break; 1716 case SCHEDULE_CRASH: 1717 throw new RemoteServiceException((String)msg.obj); 1718 case DUMP_HEAP: 1719 handleDumpHeap((DumpHeapData) msg.obj); 1720 break; 1721 case DUMP_ACTIVITY: 1722 handleDumpActivity((DumpComponentInfo)msg.obj); 1723 break; 1724 case DUMP_PROVIDER: 1725 handleDumpProvider((DumpComponentInfo)msg.obj); 1726 break; 1727 case SLEEPING: 1728 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping"); 1729 handleSleeping((IBinder)msg.obj, msg.arg1 != 0); 1730 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1731 break; 1732 case SET_CORE_SETTINGS: 1733 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings"); 1734 handleSetCoreSettings((Bundle) msg.obj); 1735 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1736 break; 1737 case UPDATE_PACKAGE_COMPATIBILITY_INFO: 1738 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj); 1739 break; 1740 case TRIM_MEMORY: 1741 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory"); 1742 handleTrimMemory(msg.arg1); 1743 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1744 break; 1745 case UNSTABLE_PROVIDER_DIED: 1746 handleUnstableProviderDied((IBinder)msg.obj, false); 1747 break; 1748 case REQUEST_ASSIST_CONTEXT_EXTRAS: 1749 handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj); 1750 break; 1751 case TRANSLUCENT_CONVERSION_COMPLETE: 1752 handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1); 1753 break; 1754 case INSTALL_PROVIDER: 1755 handleInstallProvider((ProviderInfo) msg.obj); 1756 break; 1757 case ON_NEW_ACTIVITY_OPTIONS: 1758 Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj; 1759 onNewActivityOptions(pair.first, pair.second); 1760 break; 1761 case ENTER_ANIMATION_COMPLETE: 1762 handleEnterAnimationComplete((IBinder) msg.obj); 1763 break; 1764 case START_BINDER_TRACKING: 1765 handleStartBinderTracking(); 1766 break; 1767 case STOP_BINDER_TRACKING_AND_DUMP: 1768 handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj); 1769 break; 1770 case LOCAL_VOICE_INTERACTION_STARTED: 1771 handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1, 1772 (IVoiceInteractor) ((SomeArgs) msg.obj).arg2); 1773 break; 1774 case ATTACH_AGENT: { 1775 Application app = getApplication(); 1776 handleAttachAgent((String) msg.obj, app != null ? app.mLoadedApk : null); 1777 break; 1778 } 1779 case APPLICATION_INFO_CHANGED: 1780 mUpdatingSystemConfig = true; 1781 try { 1782 handleApplicationInfoChanged((ApplicationInfo) msg.obj); 1783 } finally { 1784 mUpdatingSystemConfig = false; 1785 } 1786 break; 1787 case RUN_ISOLATED_ENTRY_POINT: 1788 handleRunIsolatedEntryPoint((String) ((SomeArgs) msg.obj).arg1, 1789 (String[]) ((SomeArgs) msg.obj).arg2); 1790 break; 1791 case EXECUTE_TRANSACTION: 1792 final ClientTransaction transaction = (ClientTransaction) msg.obj; 1793 mTransactionExecutor.execute(transaction); 1794 if (isSystem()) { 1795 // Client transactions inside system process are recycled on the client side 1796 // instead of ClientLifecycleManager to avoid being cleared before this 1797 // message is handled. 1798 transaction.recycle(); 1799 } 1800 break; 1801 } 1802 Object obj = msg.obj; 1803 if (obj instanceof SomeArgs) { 1804 ((SomeArgs) obj).recycle(); 1805 } 1806 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); 1807 } 1808 } 1809 1810 private class Idler implements MessageQueue.IdleHandler { 1811 @Override 1812 public final boolean queueIdle() { 1813 ActivityClientRecord a = mNewActivities; 1814 boolean stopProfiling = false; 1815 if (mBoundApplication != null && mProfiler.profileFd != null 1816 && mProfiler.autoStopProfiler) { 1817 stopProfiling = true; 1818 } 1819 if (a != null) { 1820 mNewActivities = null; 1821 IActivityManager am = ActivityManager.getService(); 1822 ActivityClientRecord prev; 1823 do { 1824 if (localLOGV) Slog.v( 1825 TAG, "Reporting idle of " + a + 1826 " finished=" + 1827 (a.activity != null && a.activity.mFinished)); 1828 if (a.activity != null && !a.activity.mFinished) { 1829 try { 1830 am.activityIdle(a.token, a.createdConfig, stopProfiling); 1831 a.createdConfig = null; 1832 } catch (RemoteException ex) { 1833 throw ex.rethrowFromSystemServer(); 1834 } 1835 } 1836 prev = a; 1837 a = a.nextIdle; 1838 prev.nextIdle = null; 1839 } while (a != null); 1840 } 1841 if (stopProfiling) { 1842 mProfiler.stopProfiling(); 1843 } 1844 ensureJitEnabled(); 1845 return false; 1846 } 1847 } 1848 1849 final class GcIdler implements MessageQueue.IdleHandler { 1850 @Override 1851 public final boolean queueIdle() { 1852 doGcIfNeeded(); 1853 return false; 1854 } 1855 } 1856 1857 public static ActivityThread currentActivityThread() { 1858 return sCurrentActivityThread; 1859 } 1860 1861 public static boolean isSystem() { 1862 return (sCurrentActivityThread != null) ? sCurrentActivityThread.mSystemThread : false; 1863 } 1864 1865 public static String currentOpPackageName() { 1866 ActivityThread am = currentActivityThread(); 1867 return (am != null && am.getApplication() != null) 1868 ? am.getApplication().getOpPackageName() : null; 1869 } 1870 1871 public static String currentPackageName() { 1872 ActivityThread am = currentActivityThread(); 1873 return (am != null && am.mBoundApplication != null) 1874 ? am.mBoundApplication.appInfo.packageName : null; 1875 } 1876 1877 public static String currentProcessName() { 1878 ActivityThread am = currentActivityThread(); 1879 return (am != null && am.mBoundApplication != null) 1880 ? am.mBoundApplication.processName : null; 1881 } 1882 1883 public static Application currentApplication() { 1884 ActivityThread am = currentActivityThread(); 1885 return am != null ? am.mInitialApplication : null; 1886 } 1887 1888 public static IPackageManager getPackageManager() { 1889 if (sPackageManager != null) { 1890 //Slog.v("PackageManager", "returning cur default = " + sPackageManager); 1891 return sPackageManager; 1892 } 1893 IBinder b = ServiceManager.getService("package"); 1894 //Slog.v("PackageManager", "default service binder = " + b); 1895 sPackageManager = IPackageManager.Stub.asInterface(b); 1896 //Slog.v("PackageManager", "default service = " + sPackageManager); 1897 return sPackageManager; 1898 } 1899 1900 private Configuration mMainThreadConfig = new Configuration(); 1901 1902 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config, 1903 CompatibilityInfo compat) { 1904 if (config == null) { 1905 return null; 1906 } 1907 if (!compat.supportsScreen()) { 1908 mMainThreadConfig.setTo(config); 1909 config = mMainThreadConfig; 1910 compat.applyToConfiguration(displayDensity, config); 1911 } 1912 return config; 1913 } 1914 1915 /** 1916 * Creates the top level resources for the given package. Will return an existing 1917 * Resources if one has already been created. 1918 */ 1919 Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs, 1920 String[] libDirs, int displayId, LoadedApk pkgInfo) { 1921 return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs, 1922 displayId, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader()); 1923 } 1924 1925 final Handler getHandler() { 1926 return mH; 1927 } 1928 1929 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, 1930 int flags) { 1931 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId()); 1932 } 1933 1934 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, 1935 int flags, int userId) { 1936 final boolean differentUser = (UserHandle.myUserId() != userId); 1937 synchronized (mResourcesManager) { 1938 WeakReference<LoadedApk> ref; 1939 if (differentUser) { 1940 // Caching not supported across users 1941 ref = null; 1942 } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) { 1943 ref = mPackages.get(packageName); 1944 } else { 1945 ref = mResourcePackages.get(packageName); 1946 } 1947 1948 LoadedApk packageInfo = ref != null ? ref.get() : null; 1949 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo); 1950 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir 1951 // + ": " + packageInfo.mResources.getAssets().isUpToDate()); 1952 if (packageInfo != null && (packageInfo.mResources == null 1953 || packageInfo.mResources.getAssets().isUpToDate())) { 1954 if (packageInfo.isSecurityViolation() 1955 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) { 1956 throw new SecurityException( 1957 "Requesting code from " + packageName 1958 + " to be run in process " 1959 + mBoundApplication.processName 1960 + "/" + mBoundApplication.appInfo.uid); 1961 } 1962 return packageInfo; 1963 } 1964 } 1965 1966 ApplicationInfo ai = null; 1967 try { 1968 ai = getPackageManager().getApplicationInfo(packageName, 1969 PackageManager.GET_SHARED_LIBRARY_FILES 1970 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING, 1971 userId); 1972 } catch (RemoteException e) { 1973 throw e.rethrowFromSystemServer(); 1974 } 1975 1976 if (ai != null) { 1977 return getPackageInfo(ai, compatInfo, flags); 1978 } 1979 1980 return null; 1981 } 1982 1983 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo, 1984 int flags) { 1985 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0; 1986 boolean securityViolation = includeCode && ai.uid != 0 1987 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null 1988 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid) 1989 : true); 1990 boolean registerPackage = includeCode && (flags&Context.CONTEXT_REGISTER_PACKAGE) != 0; 1991 if ((flags&(Context.CONTEXT_INCLUDE_CODE 1992 |Context.CONTEXT_IGNORE_SECURITY)) 1993 == Context.CONTEXT_INCLUDE_CODE) { 1994 if (securityViolation) { 1995 String msg = "Requesting code from " + ai.packageName 1996 + " (with uid " + ai.uid + ")"; 1997 if (mBoundApplication != null) { 1998 msg = msg + " to be run in process " 1999 + mBoundApplication.processName + " (with uid " 2000 + mBoundApplication.appInfo.uid + ")"; 2001 } 2002 throw new SecurityException(msg); 2003 } 2004 } 2005 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode, 2006 registerPackage); 2007 } 2008 2009 @Override 2010 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, 2011 CompatibilityInfo compatInfo) { 2012 return getPackageInfo(ai, compatInfo, null, false, true, false); 2013 } 2014 2015 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) { 2016 synchronized (mResourcesManager) { 2017 WeakReference<LoadedApk> ref; 2018 if (includeCode) { 2019 ref = mPackages.get(packageName); 2020 } else { 2021 ref = mResourcePackages.get(packageName); 2022 } 2023 return ref != null ? ref.get() : null; 2024 } 2025 } 2026 2027 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo, 2028 ClassLoader baseLoader, boolean securityViolation, boolean includeCode, 2029 boolean registerPackage) { 2030 final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid)); 2031 synchronized (mResourcesManager) { 2032 WeakReference<LoadedApk> ref; 2033 if (differentUser) { 2034 // Caching not supported across users 2035 ref = null; 2036 } else if (includeCode) { 2037 ref = mPackages.get(aInfo.packageName); 2038 } else { 2039 ref = mResourcePackages.get(aInfo.packageName); 2040 } 2041 2042 LoadedApk packageInfo = ref != null ? ref.get() : null; 2043 if (packageInfo == null || (packageInfo.mResources != null 2044 && !packageInfo.mResources.getAssets().isUpToDate())) { 2045 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package " 2046 : "Loading resource-only package ") + aInfo.packageName 2047 + " (in " + (mBoundApplication != null 2048 ? mBoundApplication.processName : null) 2049 + ")"); 2050 packageInfo = 2051 new LoadedApk(this, aInfo, compatInfo, baseLoader, 2052 securityViolation, includeCode && 2053 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage); 2054 2055 if (mSystemThread && "android".equals(aInfo.packageName)) { 2056 packageInfo.installSystemApplicationInfo(aInfo, 2057 getSystemContext().mPackageInfo.getClassLoader()); 2058 } 2059 2060 if (differentUser) { 2061 // Caching not supported across users 2062 } else if (includeCode) { 2063 mPackages.put(aInfo.packageName, 2064 new WeakReference<LoadedApk>(packageInfo)); 2065 } else { 2066 mResourcePackages.put(aInfo.packageName, 2067 new WeakReference<LoadedApk>(packageInfo)); 2068 } 2069 } 2070 return packageInfo; 2071 } 2072 } 2073 2074 ActivityThread() { 2075 mResourcesManager = ResourcesManager.getInstance(); 2076 } 2077 2078 public ApplicationThread getApplicationThread() 2079 { 2080 return mAppThread; 2081 } 2082 2083 public Instrumentation getInstrumentation() 2084 { 2085 return mInstrumentation; 2086 } 2087 2088 public boolean isProfiling() { 2089 return mProfiler != null && mProfiler.profileFile != null 2090 && mProfiler.profileFd == null; 2091 } 2092 2093 public String getProfileFilePath() { 2094 return mProfiler.profileFile; 2095 } 2096 2097 public Looper getLooper() { 2098 return mLooper; 2099 } 2100 2101 public Executor getExecutor() { 2102 return mExecutor; 2103 } 2104 2105 public Application getApplication() { 2106 return mInitialApplication; 2107 } 2108 2109 public String getProcessName() { 2110 return mBoundApplication.processName; 2111 } 2112 2113 public ContextImpl getSystemContext() { 2114 synchronized (this) { 2115 if (mSystemContext == null) { 2116 mSystemContext = ContextImpl.createSystemContext(this); 2117 } 2118 return mSystemContext; 2119 } 2120 } 2121 2122 public ContextImpl getSystemUiContext() { 2123 synchronized (this) { 2124 if (mSystemUiContext == null) { 2125 mSystemUiContext = ContextImpl.createSystemUiContext(getSystemContext()); 2126 } 2127 return mSystemUiContext; 2128 } 2129 } 2130 2131 public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { 2132 synchronized (this) { 2133 getSystemContext().installSystemApplicationInfo(info, classLoader); 2134 getSystemUiContext().installSystemApplicationInfo(info, classLoader); 2135 2136 // give ourselves a default profiler 2137 mProfiler = new Profiler(); 2138 } 2139 } 2140 2141 void ensureJitEnabled() { 2142 if (!mJitEnabled) { 2143 mJitEnabled = true; 2144 dalvik.system.VMRuntime.getRuntime().startJitCompilation(); 2145 } 2146 } 2147 2148 void scheduleGcIdler() { 2149 if (!mGcIdlerScheduled) { 2150 mGcIdlerScheduled = true; 2151 Looper.myQueue().addIdleHandler(mGcIdler); 2152 } 2153 mH.removeMessages(H.GC_WHEN_IDLE); 2154 } 2155 2156 void unscheduleGcIdler() { 2157 if (mGcIdlerScheduled) { 2158 mGcIdlerScheduled = false; 2159 Looper.myQueue().removeIdleHandler(mGcIdler); 2160 } 2161 mH.removeMessages(H.GC_WHEN_IDLE); 2162 } 2163 2164 void doGcIfNeeded() { 2165 mGcIdlerScheduled = false; 2166 final long now = SystemClock.uptimeMillis(); 2167 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime() 2168 // + "m now=" + now); 2169 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) { 2170 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!"); 2171 BinderInternal.forceGc("bg"); 2172 } 2173 } 2174 2175 private static final String HEAP_FULL_COLUMN 2176 = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; 2177 private static final String HEAP_COLUMN 2178 = "%13s %8s %8s %8s %8s %8s %8s %8s"; 2179 private static final String ONE_COUNT_COLUMN = "%21s %8d"; 2180 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d"; 2181 private static final String ONE_COUNT_COLUMN_HEADER = "%21s %8s"; 2182 2183 // Formatting for checkin service - update version if row format changes 2184 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 4; 2185 2186 static void printRow(PrintWriter pw, String format, Object...objs) { 2187 pw.println(String.format(format, objs)); 2188 } 2189 2190 @Override 2191 public void dump(PrintWriter pw, String prefix) { 2192 pw.println(prefix + "Activities:"); 2193 2194 if (!mActivities.isEmpty()) { 2195 final Iterator<Map.Entry<IBinder, ActivityClientRecord>> activitiesIterator = 2196 mActivities.entrySet().iterator(); 2197 2198 while (activitiesIterator.hasNext()) { 2199 final ArrayMap.Entry<IBinder, ActivityClientRecord> entry = 2200 activitiesIterator.next(); 2201 pw.println(prefix + " [token:" + entry.getKey().hashCode() + " record:" 2202 + entry.getValue().toString() + "]"); 2203 } 2204 } 2205 2206 if (!mRecentDestroyedActivities.isEmpty()) { 2207 pw.println(prefix + "Recent destroyed activities:"); 2208 for (int i = 0, size = mRecentDestroyedActivities.size(); i < size; i++) { 2209 final DestroyedActivityInfo info = mRecentDestroyedActivities.get(i); 2210 pw.print(prefix); 2211 info.dump(pw, " "); 2212 } 2213 } 2214 } 2215 2216 public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 2217 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, 2218 int pid, String processName, 2219 long nativeMax, long nativeAllocated, long nativeFree, 2220 long dalvikMax, long dalvikAllocated, long dalvikFree) { 2221 2222 // For checkin, we print one long comma-separated list of values 2223 if (checkin) { 2224 // NOTE: if you change anything significant below, also consider changing 2225 // ACTIVITY_THREAD_CHECKIN_VERSION. 2226 2227 // Header 2228 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(','); 2229 pw.print(pid); pw.print(','); 2230 pw.print(processName); pw.print(','); 2231 2232 // Heap info - max 2233 pw.print(nativeMax); pw.print(','); 2234 pw.print(dalvikMax); pw.print(','); 2235 pw.print("N/A,"); 2236 pw.print(nativeMax + dalvikMax); pw.print(','); 2237 2238 // Heap info - allocated 2239 pw.print(nativeAllocated); pw.print(','); 2240 pw.print(dalvikAllocated); pw.print(','); 2241 pw.print("N/A,"); 2242 pw.print(nativeAllocated + dalvikAllocated); pw.print(','); 2243 2244 // Heap info - free 2245 pw.print(nativeFree); pw.print(','); 2246 pw.print(dalvikFree); pw.print(','); 2247 pw.print("N/A,"); 2248 pw.print(nativeFree + dalvikFree); pw.print(','); 2249 2250 // Heap info - proportional set size 2251 pw.print(memInfo.nativePss); pw.print(','); 2252 pw.print(memInfo.dalvikPss); pw.print(','); 2253 pw.print(memInfo.otherPss); pw.print(','); 2254 pw.print(memInfo.getTotalPss()); pw.print(','); 2255 2256 // Heap info - swappable set size 2257 pw.print(memInfo.nativeSwappablePss); pw.print(','); 2258 pw.print(memInfo.dalvikSwappablePss); pw.print(','); 2259 pw.print(memInfo.otherSwappablePss); pw.print(','); 2260 pw.print(memInfo.getTotalSwappablePss()); pw.print(','); 2261 2262 // Heap info - shared dirty 2263 pw.print(memInfo.nativeSharedDirty); pw.print(','); 2264 pw.print(memInfo.dalvikSharedDirty); pw.print(','); 2265 pw.print(memInfo.otherSharedDirty); pw.print(','); 2266 pw.print(memInfo.getTotalSharedDirty()); pw.print(','); 2267 2268 // Heap info - shared clean 2269 pw.print(memInfo.nativeSharedClean); pw.print(','); 2270 pw.print(memInfo.dalvikSharedClean); pw.print(','); 2271 pw.print(memInfo.otherSharedClean); pw.print(','); 2272 pw.print(memInfo.getTotalSharedClean()); pw.print(','); 2273 2274 // Heap info - private Dirty 2275 pw.print(memInfo.nativePrivateDirty); pw.print(','); 2276 pw.print(memInfo.dalvikPrivateDirty); pw.print(','); 2277 pw.print(memInfo.otherPrivateDirty); pw.print(','); 2278 pw.print(memInfo.getTotalPrivateDirty()); pw.print(','); 2279 2280 // Heap info - private Clean 2281 pw.print(memInfo.nativePrivateClean); pw.print(','); 2282 pw.print(memInfo.dalvikPrivateClean); pw.print(','); 2283 pw.print(memInfo.otherPrivateClean); pw.print(','); 2284 pw.print(memInfo.getTotalPrivateClean()); pw.print(','); 2285 2286 // Heap info - swapped out 2287 pw.print(memInfo.nativeSwappedOut); pw.print(','); 2288 pw.print(memInfo.dalvikSwappedOut); pw.print(','); 2289 pw.print(memInfo.otherSwappedOut); pw.print(','); 2290 pw.print(memInfo.getTotalSwappedOut()); pw.print(','); 2291 2292 // Heap info - swapped out pss 2293 if (memInfo.hasSwappedOutPss) { 2294 pw.print(memInfo.nativeSwappedOutPss); pw.print(','); 2295 pw.print(memInfo.dalvikSwappedOutPss); pw.print(','); 2296 pw.print(memInfo.otherSwappedOutPss); pw.print(','); 2297 pw.print(memInfo.getTotalSwappedOutPss()); pw.print(','); 2298 } else { 2299 pw.print("N/A,"); 2300 pw.print("N/A,"); 2301 pw.print("N/A,"); 2302 pw.print("N/A,"); 2303 } 2304 2305 // Heap info - other areas 2306 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) { 2307 pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(','); 2308 pw.print(memInfo.getOtherPss(i)); pw.print(','); 2309 pw.print(memInfo.getOtherSwappablePss(i)); pw.print(','); 2310 pw.print(memInfo.getOtherSharedDirty(i)); pw.print(','); 2311 pw.print(memInfo.getOtherSharedClean(i)); pw.print(','); 2312 pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(','); 2313 pw.print(memInfo.getOtherPrivateClean(i)); pw.print(','); 2314 pw.print(memInfo.getOtherSwappedOut(i)); pw.print(','); 2315 if (memInfo.hasSwappedOutPss) { 2316 pw.print(memInfo.getOtherSwappedOutPss(i)); pw.print(','); 2317 } else { 2318 pw.print("N/A,"); 2319 } 2320 } 2321 return; 2322 } 2323 2324 if (!dumpSummaryOnly) { 2325 if (dumpFullInfo) { 2326 printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private", 2327 "Shared", "Private", memInfo.hasSwappedOutPss ? "SwapPss" : "Swap", 2328 "Heap", "Heap", "Heap"); 2329 printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty", 2330 "Clean", "Clean", "Dirty", 2331 "Size", "Alloc", "Free"); 2332 printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------", 2333 "------", "------", "------", "------", "------", "------"); 2334 printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss, 2335 memInfo.nativeSwappablePss, memInfo.nativeSharedDirty, 2336 memInfo.nativePrivateDirty, memInfo.nativeSharedClean, 2337 memInfo.nativePrivateClean, memInfo.hasSwappedOutPss ? 2338 memInfo.nativeSwappedOutPss : memInfo.nativeSwappedOut, 2339 nativeMax, nativeAllocated, nativeFree); 2340 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss, 2341 memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty, 2342 memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, 2343 memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss ? 2344 memInfo.dalvikSwappedOutPss : memInfo.dalvikSwappedOut, 2345 dalvikMax, dalvikAllocated, dalvikFree); 2346 } else { 2347 printRow(pw, HEAP_COLUMN, "", "Pss", "Private", 2348 "Private", memInfo.hasSwappedOutPss ? "SwapPss" : "Swap", 2349 "Heap", "Heap", "Heap"); 2350 printRow(pw, HEAP_COLUMN, "", "Total", "Dirty", 2351 "Clean", "Dirty", "Size", "Alloc", "Free"); 2352 printRow(pw, HEAP_COLUMN, "", "------", "------", "------", 2353 "------", "------", "------", "------", "------"); 2354 printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss, 2355 memInfo.nativePrivateDirty, 2356 memInfo.nativePrivateClean, 2357 memInfo.hasSwappedOutPss ? memInfo.nativeSwappedOutPss : 2358 memInfo.nativeSwappedOut, 2359 nativeMax, nativeAllocated, nativeFree); 2360 printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss, 2361 memInfo.dalvikPrivateDirty, 2362 memInfo.dalvikPrivateClean, 2363 memInfo.hasSwappedOutPss ? memInfo.dalvikSwappedOutPss : 2364 memInfo.dalvikSwappedOut, 2365 dalvikMax, dalvikAllocated, dalvikFree); 2366 } 2367 2368 int otherPss = memInfo.otherPss; 2369 int otherSwappablePss = memInfo.otherSwappablePss; 2370 int otherSharedDirty = memInfo.otherSharedDirty; 2371 int otherPrivateDirty = memInfo.otherPrivateDirty; 2372 int otherSharedClean = memInfo.otherSharedClean; 2373 int otherPrivateClean = memInfo.otherPrivateClean; 2374 int otherSwappedOut = memInfo.otherSwappedOut; 2375 int otherSwappedOutPss = memInfo.otherSwappedOutPss; 2376 2377 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) { 2378 final int myPss = memInfo.getOtherPss(i); 2379 final int mySwappablePss = memInfo.getOtherSwappablePss(i); 2380 final int mySharedDirty = memInfo.getOtherSharedDirty(i); 2381 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); 2382 final int mySharedClean = memInfo.getOtherSharedClean(i); 2383 final int myPrivateClean = memInfo.getOtherPrivateClean(i); 2384 final int mySwappedOut = memInfo.getOtherSwappedOut(i); 2385 final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i); 2386 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 2387 || mySharedClean != 0 || myPrivateClean != 0 2388 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) { 2389 if (dumpFullInfo) { 2390 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 2391 myPss, mySwappablePss, mySharedDirty, myPrivateDirty, 2392 mySharedClean, myPrivateClean, 2393 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut, 2394 "", "", ""); 2395 } else { 2396 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 2397 myPss, myPrivateDirty, 2398 myPrivateClean, 2399 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut, 2400 "", "", ""); 2401 } 2402 otherPss -= myPss; 2403 otherSwappablePss -= mySwappablePss; 2404 otherSharedDirty -= mySharedDirty; 2405 otherPrivateDirty -= myPrivateDirty; 2406 otherSharedClean -= mySharedClean; 2407 otherPrivateClean -= myPrivateClean; 2408 otherSwappedOut -= mySwappedOut; 2409 otherSwappedOutPss -= mySwappedOutPss; 2410 } 2411 } 2412 2413 if (dumpFullInfo) { 2414 printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss, 2415 otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean, 2416 memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut, 2417 "", "", ""); 2418 printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(), 2419 memInfo.getTotalSwappablePss(), 2420 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), 2421 memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), 2422 memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() : 2423 memInfo.getTotalSwappedOut(), 2424 nativeMax+dalvikMax, nativeAllocated+dalvikAllocated, 2425 nativeFree+dalvikFree); 2426 } else { 2427 printRow(pw, HEAP_COLUMN, "Unknown", otherPss, 2428 otherPrivateDirty, otherPrivateClean, 2429 memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut, 2430 "", "", ""); 2431 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(), 2432 memInfo.getTotalPrivateDirty(), 2433 memInfo.getTotalPrivateClean(), 2434 memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() : 2435 memInfo.getTotalSwappedOut(), 2436 nativeMax+dalvikMax, 2437 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); 2438 } 2439 2440 if (dumpDalvik) { 2441 pw.println(" "); 2442 pw.println(" Dalvik Details"); 2443 2444 for (int i=Debug.MemoryInfo.NUM_OTHER_STATS; 2445 i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) { 2446 final int myPss = memInfo.getOtherPss(i); 2447 final int mySwappablePss = memInfo.getOtherSwappablePss(i); 2448 final int mySharedDirty = memInfo.getOtherSharedDirty(i); 2449 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); 2450 final int mySharedClean = memInfo.getOtherSharedClean(i); 2451 final int myPrivateClean = memInfo.getOtherPrivateClean(i); 2452 final int mySwappedOut = memInfo.getOtherSwappedOut(i); 2453 final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i); 2454 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 2455 || mySharedClean != 0 || myPrivateClean != 0 2456 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) { 2457 if (dumpFullInfo) { 2458 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 2459 myPss, mySwappablePss, mySharedDirty, myPrivateDirty, 2460 mySharedClean, myPrivateClean, 2461 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut, 2462 "", "", ""); 2463 } else { 2464 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 2465 myPss, myPrivateDirty, 2466 myPrivateClean, 2467 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut, 2468 "", "", ""); 2469 } 2470 } 2471 } 2472 } 2473 } 2474 2475 pw.println(" "); 2476 pw.println(" App Summary"); 2477 printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "Pss(KB)"); 2478 printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "------"); 2479 printRow(pw, ONE_COUNT_COLUMN, 2480 "Java Heap:", memInfo.getSummaryJavaHeap()); 2481 printRow(pw, ONE_COUNT_COLUMN, 2482 "Native Heap:", memInfo.getSummaryNativeHeap()); 2483 printRow(pw, ONE_COUNT_COLUMN, 2484 "Code:", memInfo.getSummaryCode()); 2485 printRow(pw, ONE_COUNT_COLUMN, 2486 "Stack:", memInfo.getSummaryStack()); 2487 printRow(pw, ONE_COUNT_COLUMN, 2488 "Graphics:", memInfo.getSummaryGraphics()); 2489 printRow(pw, ONE_COUNT_COLUMN, 2490 "Private Other:", memInfo.getSummaryPrivateOther()); 2491 printRow(pw, ONE_COUNT_COLUMN, 2492 "System:", memInfo.getSummarySystem()); 2493 pw.println(" "); 2494 if (memInfo.hasSwappedOutPss) { 2495 printRow(pw, TWO_COUNT_COLUMNS, 2496 "TOTAL:", memInfo.getSummaryTotalPss(), 2497 "TOTAL SWAP PSS:", memInfo.getSummaryTotalSwapPss()); 2498 } else { 2499 printRow(pw, TWO_COUNT_COLUMNS, 2500 "TOTAL:", memInfo.getSummaryTotalPss(), 2501 "TOTAL SWAP (KB):", memInfo.getSummaryTotalSwap()); 2502 } 2503 } 2504 2505 /** 2506 * Dump heap info to proto. 2507 * 2508 * @param hasSwappedOutPss determines whether to use dirtySwap or dirtySwapPss 2509 */ 2510 private static void dumpMemoryInfo(ProtoOutputStream proto, long fieldId, String name, 2511 int pss, int cleanPss, int sharedDirty, int privateDirty, 2512 int sharedClean, int privateClean, 2513 boolean hasSwappedOutPss, int dirtySwap, int dirtySwapPss) { 2514 final long token = proto.start(fieldId); 2515 2516 proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.NAME, name); 2517 proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.TOTAL_PSS_KB, pss); 2518 proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.CLEAN_PSS_KB, cleanPss); 2519 proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.SHARED_DIRTY_KB, sharedDirty); 2520 proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty); 2521 proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.SHARED_CLEAN_KB, sharedClean); 2522 proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.PRIVATE_CLEAN_KB, privateClean); 2523 if (hasSwappedOutPss) { 2524 proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss); 2525 } else { 2526 proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_KB, dirtySwap); 2527 } 2528 2529 proto.end(token); 2530 } 2531 2532 /** 2533 * Dump mem info data to proto. 2534 */ 2535 public static void dumpMemInfoTable(ProtoOutputStream proto, Debug.MemoryInfo memInfo, 2536 boolean dumpDalvik, boolean dumpSummaryOnly, 2537 long nativeMax, long nativeAllocated, long nativeFree, 2538 long dalvikMax, long dalvikAllocated, long dalvikFree) { 2539 2540 if (!dumpSummaryOnly) { 2541 final long nhToken = proto.start(MemInfoDumpProto.ProcessMemory.NATIVE_HEAP); 2542 dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "Native Heap", 2543 memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty, 2544 memInfo.nativePrivateDirty, memInfo.nativeSharedClean, 2545 memInfo.nativePrivateClean, memInfo.hasSwappedOutPss, 2546 memInfo.nativeSwappedOut, memInfo.nativeSwappedOutPss); 2547 proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax); 2548 proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, nativeAllocated); 2549 proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree); 2550 proto.end(nhToken); 2551 2552 final long dvToken = proto.start(MemInfoDumpProto.ProcessMemory.DALVIK_HEAP); 2553 dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "Dalvik Heap", 2554 memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty, 2555 memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, 2556 memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss, 2557 memInfo.dalvikSwappedOut, memInfo.dalvikSwappedOutPss); 2558 proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, dalvikMax); 2559 proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated); 2560 proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, dalvikFree); 2561 proto.end(dvToken); 2562 2563 int otherPss = memInfo.otherPss; 2564 int otherSwappablePss = memInfo.otherSwappablePss; 2565 int otherSharedDirty = memInfo.otherSharedDirty; 2566 int otherPrivateDirty = memInfo.otherPrivateDirty; 2567 int otherSharedClean = memInfo.otherSharedClean; 2568 int otherPrivateClean = memInfo.otherPrivateClean; 2569 int otherSwappedOut = memInfo.otherSwappedOut; 2570 int otherSwappedOutPss = memInfo.otherSwappedOutPss; 2571 2572 for (int i = 0; i < Debug.MemoryInfo.NUM_OTHER_STATS; i++) { 2573 final int myPss = memInfo.getOtherPss(i); 2574 final int mySwappablePss = memInfo.getOtherSwappablePss(i); 2575 final int mySharedDirty = memInfo.getOtherSharedDirty(i); 2576 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); 2577 final int mySharedClean = memInfo.getOtherSharedClean(i); 2578 final int myPrivateClean = memInfo.getOtherPrivateClean(i); 2579 final int mySwappedOut = memInfo.getOtherSwappedOut(i); 2580 final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i); 2581 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 2582 || mySharedClean != 0 || myPrivateClean != 0 2583 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) { 2584 dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.OTHER_HEAPS, 2585 Debug.MemoryInfo.getOtherLabel(i), 2586 myPss, mySwappablePss, mySharedDirty, myPrivateDirty, 2587 mySharedClean, myPrivateClean, 2588 memInfo.hasSwappedOutPss, mySwappedOut, mySwappedOutPss); 2589 2590 otherPss -= myPss; 2591 otherSwappablePss -= mySwappablePss; 2592 otherSharedDirty -= mySharedDirty; 2593 otherPrivateDirty -= myPrivateDirty; 2594 otherSharedClean -= mySharedClean; 2595 otherPrivateClean -= myPrivateClean; 2596 otherSwappedOut -= mySwappedOut; 2597 otherSwappedOutPss -= mySwappedOutPss; 2598 } 2599 } 2600 2601 dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.UNKNOWN_HEAP, "Unknown", 2602 otherPss, otherSwappablePss, 2603 otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean, 2604 memInfo.hasSwappedOutPss, otherSwappedOut, otherSwappedOutPss); 2605 final long tToken = proto.start(MemInfoDumpProto.ProcessMemory.TOTAL_HEAP); 2606 dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "TOTAL", 2607 memInfo.getTotalPss(), memInfo.getTotalSwappablePss(), 2608 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), 2609 memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), 2610 memInfo.hasSwappedOutPss, memInfo.getTotalSwappedOut(), 2611 memInfo.getTotalSwappedOutPss()); 2612 proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, 2613 nativeMax + dalvikMax); 2614 proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, 2615 nativeAllocated + dalvikAllocated); 2616 proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, 2617 nativeFree + dalvikFree); 2618 proto.end(tToken); 2619 2620 if (dumpDalvik) { 2621 for (int i = Debug.MemoryInfo.NUM_OTHER_STATS; 2622 i < Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; 2623 i++) { 2624 final int myPss = memInfo.getOtherPss(i); 2625 final int mySwappablePss = memInfo.getOtherSwappablePss(i); 2626 final int mySharedDirty = memInfo.getOtherSharedDirty(i); 2627 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); 2628 final int mySharedClean = memInfo.getOtherSharedClean(i); 2629 final int myPrivateClean = memInfo.getOtherPrivateClean(i); 2630 final int mySwappedOut = memInfo.getOtherSwappedOut(i); 2631 final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i); 2632 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 2633 || mySharedClean != 0 || myPrivateClean != 0 2634 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) { 2635 dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.DALVIK_DETAILS, 2636 Debug.MemoryInfo.getOtherLabel(i), 2637 myPss, mySwappablePss, mySharedDirty, myPrivateDirty, 2638 mySharedClean, myPrivateClean, 2639 memInfo.hasSwappedOutPss, mySwappedOut, mySwappedOutPss); 2640 } 2641 } 2642 } 2643 } 2644 2645 final long asToken = proto.start(MemInfoDumpProto.ProcessMemory.APP_SUMMARY); 2646 proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.JAVA_HEAP_PSS_KB, 2647 memInfo.getSummaryJavaHeap()); 2648 proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.NATIVE_HEAP_PSS_KB, 2649 memInfo.getSummaryNativeHeap()); 2650 proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.CODE_PSS_KB, 2651 memInfo.getSummaryCode()); 2652 proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.STACK_PSS_KB, 2653 memInfo.getSummaryStack()); 2654 proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.GRAPHICS_PSS_KB, 2655 memInfo.getSummaryGraphics()); 2656 proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.PRIVATE_OTHER_PSS_KB, 2657 memInfo.getSummaryPrivateOther()); 2658 proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.SYSTEM_PSS_KB, 2659 memInfo.getSummarySystem()); 2660 if (memInfo.hasSwappedOutPss) { 2661 proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS, 2662 memInfo.getSummaryTotalSwapPss()); 2663 } else { 2664 proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS, 2665 memInfo.getSummaryTotalSwap()); 2666 } 2667 proto.end(asToken); 2668 } 2669 2670 public void registerOnActivityPausedListener(Activity activity, 2671 OnActivityPausedListener listener) { 2672 synchronized (mOnPauseListeners) { 2673 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity); 2674 if (list == null) { 2675 list = new ArrayList<OnActivityPausedListener>(); 2676 mOnPauseListeners.put(activity, list); 2677 } 2678 list.add(listener); 2679 } 2680 } 2681 2682 public void unregisterOnActivityPausedListener(Activity activity, 2683 OnActivityPausedListener listener) { 2684 synchronized (mOnPauseListeners) { 2685 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity); 2686 if (list != null) { 2687 list.remove(listener); 2688 } 2689 } 2690 } 2691 2692 public final ActivityInfo resolveActivityInfo(Intent intent) { 2693 ActivityInfo aInfo = intent.resolveActivityInfo( 2694 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES); 2695 if (aInfo == null) { 2696 // Throw an exception. 2697 Instrumentation.checkStartActivityResult( 2698 ActivityManager.START_CLASS_NOT_FOUND, intent); 2699 } 2700 return aInfo; 2701 } 2702 2703 public final Activity startActivityNow(Activity parent, String id, 2704 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state, 2705 Activity.NonConfigurationInstances lastNonConfigurationInstances) { 2706 ActivityClientRecord r = new ActivityClientRecord(); 2707 r.token = token; 2708 r.ident = 0; 2709 r.intent = intent; 2710 r.state = state; 2711 r.parent = parent; 2712 r.embeddedID = id; 2713 r.activityInfo = activityInfo; 2714 r.lastNonConfigurationInstances = lastNonConfigurationInstances; 2715 if (localLOGV) { 2716 ComponentName compname = intent.getComponent(); 2717 String name; 2718 if (compname != null) { 2719 name = compname.toShortString(); 2720 } else { 2721 name = "(Intent " + intent + ").getComponent() returned null"; 2722 } 2723 Slog.v(TAG, "Performing launch: action=" + intent.getAction() 2724 + ", comp=" + name 2725 + ", token=" + token); 2726 } 2727 // TODO(lifecycler): Can't switch to use #handleLaunchActivity() because it will try to 2728 // call #reportSizeConfigurations(), but the server might not know anything about the 2729 // activity if it was launched from LocalAcvitivyManager. 2730 return performLaunchActivity(r); 2731 } 2732 2733 public final Activity getActivity(IBinder token) { 2734 return mActivities.get(token).activity; 2735 } 2736 2737 @Override 2738 public ActivityClientRecord getActivityClient(IBinder token) { 2739 return mActivities.get(token); 2740 } 2741 2742 public final void sendActivityResult( 2743 IBinder token, String id, int requestCode, 2744 int resultCode, Intent data) { 2745 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id 2746 + " req=" + requestCode + " res=" + resultCode + " data=" + data); 2747 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 2748 list.add(new ResultInfo(id, requestCode, resultCode, data)); 2749 final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread, token); 2750 clientTransaction.addCallback(ActivityResultItem.obtain(list)); 2751 try { 2752 mAppThread.scheduleTransaction(clientTransaction); 2753 } catch (RemoteException e) { 2754 // Local scheduling 2755 } 2756 } 2757 2758 void sendMessage(int what, Object obj) { 2759 sendMessage(what, obj, 0, 0, false); 2760 } 2761 2762 private void sendMessage(int what, Object obj, int arg1) { 2763 sendMessage(what, obj, arg1, 0, false); 2764 } 2765 2766 private void sendMessage(int what, Object obj, int arg1, int arg2) { 2767 sendMessage(what, obj, arg1, arg2, false); 2768 } 2769 2770 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { 2771 if (DEBUG_MESSAGES) Slog.v( 2772 TAG, "SCHEDULE " + what + " " + mH.codeToString(what) 2773 + ": " + arg1 + " / " + obj); 2774 Message msg = Message.obtain(); 2775 msg.what = what; 2776 msg.obj = obj; 2777 msg.arg1 = arg1; 2778 msg.arg2 = arg2; 2779 if (async) { 2780 msg.setAsynchronous(true); 2781 } 2782 mH.sendMessage(msg); 2783 } 2784 2785 private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) { 2786 if (DEBUG_MESSAGES) Slog.v( 2787 TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 + 2788 "seq= " + seq); 2789 Message msg = Message.obtain(); 2790 msg.what = what; 2791 SomeArgs args = SomeArgs.obtain(); 2792 args.arg1 = obj; 2793 args.argi1 = arg1; 2794 args.argi2 = arg2; 2795 args.argi3 = seq; 2796 msg.obj = args; 2797 mH.sendMessage(msg); 2798 } 2799 2800 final void scheduleContextCleanup(ContextImpl context, String who, 2801 String what) { 2802 ContextCleanupInfo cci = new ContextCleanupInfo(); 2803 cci.context = context; 2804 cci.who = who; 2805 cci.what = what; 2806 sendMessage(H.CLEAN_UP_CONTEXT, cci); 2807 } 2808 2809 /** Core implementation of activity launch. */ 2810 private Activity performLaunchActivity(ActivityClientRecord r) { 2811 ActivityInfo aInfo = r.activityInfo; 2812 if (r.packageInfo == null) { 2813 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, 2814 Context.CONTEXT_INCLUDE_CODE); 2815 } 2816 2817 ComponentName component = r.intent.getComponent(); 2818 if (component == null) { 2819 component = r.intent.resolveActivity( 2820 mInitialApplication.getPackageManager()); 2821 r.intent.setComponent(component); 2822 } 2823 2824 if (r.activityInfo.targetActivity != null) { 2825 component = new ComponentName(r.activityInfo.packageName, 2826 r.activityInfo.targetActivity); 2827 } 2828 2829 ContextImpl appContext = createBaseContextForActivity(r); 2830 Activity activity = null; 2831 try { 2832 java.lang.ClassLoader cl = appContext.getClassLoader(); 2833 activity = mInstrumentation.newActivity( 2834 cl, component.getClassName(), r.intent); 2835 StrictMode.incrementExpectedActivityCount(activity.getClass()); 2836 r.intent.setExtrasClassLoader(cl); 2837 r.intent.prepareToEnterProcess(); 2838 if (r.state != null) { 2839 r.state.setClassLoader(cl); 2840 } 2841 } catch (Exception e) { 2842 if (!mInstrumentation.onException(activity, e)) { 2843 throw new RuntimeException( 2844 "Unable to instantiate activity " + component 2845 + ": " + e.toString(), e); 2846 } 2847 } 2848 2849 try { 2850 Application app = r.packageInfo.makeApplication(false, mInstrumentation); 2851 2852 if (localLOGV) Slog.v(TAG, "Performing launch of " + r); 2853 if (localLOGV) Slog.v( 2854 TAG, r + ": app=" + app 2855 + ", appName=" + app.getPackageName() 2856 + ", pkg=" + r.packageInfo.getPackageName() 2857 + ", comp=" + r.intent.getComponent().toShortString() 2858 + ", dir=" + r.packageInfo.getAppDir()); 2859 2860 if (activity != null) { 2861 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); 2862 Configuration config = new Configuration(mCompatConfiguration); 2863 if (r.overrideConfig != null) { 2864 config.updateFrom(r.overrideConfig); 2865 } 2866 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " 2867 + r.activityInfo.name + " with config " + config); 2868 Window window = null; 2869 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { 2870 window = r.mPendingRemoveWindow; 2871 r.mPendingRemoveWindow = null; 2872 r.mPendingRemoveWindowManager = null; 2873 } 2874 appContext.setOuterContext(activity); 2875 activity.attach(appContext, this, getInstrumentation(), r.token, 2876 r.ident, app, r.intent, r.activityInfo, title, r.parent, 2877 r.embeddedID, r.lastNonConfigurationInstances, config, 2878 r.referrer, r.voiceInteractor, window, r.configCallback); 2879 2880 r.lastNonConfigurationInstances = null; 2881 checkAndBlockForNetworkAccess(); 2882 activity.mStartedActivity = false; 2883 int theme = r.activityInfo.getThemeResource(); 2884 if (theme != 0) { 2885 activity.setTheme(theme); 2886 } 2887 2888 activity.mCalled = false; 2889 if (r.isPersistable()) { 2890 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); 2891 } else { 2892 mInstrumentation.callActivityOnCreate(activity, r.state); 2893 } 2894 if (!activity.mCalled) { 2895 throw new SuperNotCalledException( 2896 "Activity " + r.intent.getComponent().toShortString() + 2897 " did not call through to super.onCreate()"); 2898 } 2899 r.activity = activity; 2900 } 2901 r.setState(ON_CREATE); 2902 2903 mActivities.put(r.token, r); 2904 2905 } catch (SuperNotCalledException e) { 2906 throw e; 2907 2908 } catch (Exception e) { 2909 if (!mInstrumentation.onException(activity, e)) { 2910 throw new RuntimeException( 2911 "Unable to start activity " + component 2912 + ": " + e.toString(), e); 2913 } 2914 } 2915 2916 return activity; 2917 } 2918 2919 @Override 2920 public void handleStartActivity(ActivityClientRecord r, 2921 PendingTransactionActions pendingActions) { 2922 final Activity activity = r.activity; 2923 if (r.activity == null) { 2924 // TODO(lifecycler): What do we do in this case? 2925 return; 2926 } 2927 if (!r.stopped) { 2928 throw new IllegalStateException("Can't start activity that is not stopped."); 2929 } 2930 if (r.activity.mFinished) { 2931 // TODO(lifecycler): How can this happen? 2932 return; 2933 } 2934 2935 // Start 2936 activity.performStart("handleStartActivity"); 2937 r.setState(ON_START); 2938 2939 if (pendingActions == null) { 2940 // No more work to do. 2941 return; 2942 } 2943 2944 // Restore instance state 2945 if (pendingActions.shouldRestoreInstanceState()) { 2946 if (r.isPersistable()) { 2947 if (r.state != null || r.persistentState != null) { 2948 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, 2949 r.persistentState); 2950 } 2951 } else if (r.state != null) { 2952 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); 2953 } 2954 } 2955 2956 // Call postOnCreate() 2957 if (pendingActions.shouldCallOnPostCreate()) { 2958 activity.mCalled = false; 2959 if (r.isPersistable()) { 2960 mInstrumentation.callActivityOnPostCreate(activity, r.state, 2961 r.persistentState); 2962 } else { 2963 mInstrumentation.callActivityOnPostCreate(activity, r.state); 2964 } 2965 if (!activity.mCalled) { 2966 throw new SuperNotCalledException( 2967 "Activity " + r.intent.getComponent().toShortString() 2968 + " did not call through to super.onPostCreate()"); 2969 } 2970 } 2971 } 2972 2973 /** 2974 * Checks if {@link #mNetworkBlockSeq} is {@link #INVALID_PROC_STATE_SEQ} and if so, returns 2975 * immediately. Otherwise, makes a blocking call to ActivityManagerService to wait for the 2976 * network rules to get updated. 2977 */ 2978 private void checkAndBlockForNetworkAccess() { 2979 synchronized (mNetworkPolicyLock) { 2980 if (mNetworkBlockSeq != INVALID_PROC_STATE_SEQ) { 2981 try { 2982 ActivityManager.getService().waitForNetworkStateUpdate(mNetworkBlockSeq); 2983 mNetworkBlockSeq = INVALID_PROC_STATE_SEQ; 2984 } catch (RemoteException ignored) {} 2985 } 2986 } 2987 } 2988 2989 private ContextImpl createBaseContextForActivity(ActivityClientRecord r) { 2990 final int displayId; 2991 try { 2992 displayId = ActivityManager.getService().getActivityDisplayId(r.token); 2993 } catch (RemoteException e) { 2994 throw e.rethrowFromSystemServer(); 2995 } 2996 2997 ContextImpl appContext = ContextImpl.createActivityContext( 2998 this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig); 2999 3000 final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3001 // For debugging purposes, if the activity's package name contains the value of 3002 // the "debug.use-second-display" system property as a substring, then show 3003 // its content on a secondary display if there is one. 3004 String pkgName = SystemProperties.get("debug.second-display.pkg"); 3005 if (pkgName != null && !pkgName.isEmpty() 3006 && r.packageInfo.mPackageName.contains(pkgName)) { 3007 for (int id : dm.getDisplayIds()) { 3008 if (id != Display.DEFAULT_DISPLAY) { 3009 Display display = 3010 dm.getCompatibleDisplay(id, appContext.getResources()); 3011 appContext = (ContextImpl) appContext.createDisplayContext(display); 3012 break; 3013 } 3014 } 3015 } 3016 return appContext; 3017 } 3018 3019 /** 3020 * Extended implementation of activity launch. Used when server requests a launch or relaunch. 3021 */ 3022 @Override 3023 public Activity handleLaunchActivity(ActivityClientRecord r, 3024 PendingTransactionActions pendingActions) { 3025 // If we are getting ready to gc after going to the background, well 3026 // we are back active so skip it. 3027 unscheduleGcIdler(); 3028 mSomeActivitiesChanged = true; 3029 3030 if (r.profilerInfo != null) { 3031 mProfiler.setProfiler(r.profilerInfo); 3032 mProfiler.startProfiling(); 3033 } 3034 3035 // Make sure we are running with the most recent config. 3036 handleConfigurationChanged(null, null); 3037 3038 if (localLOGV) Slog.v( 3039 TAG, "Handling launch of " + r); 3040 3041 // Initialize before creating the activity 3042 if (!ThreadedRenderer.sRendererDisabled) { 3043 GraphicsEnvironment.earlyInitEGL(); 3044 } 3045 WindowManagerGlobal.initialize(); 3046 3047 final Activity a = performLaunchActivity(r); 3048 3049 if (a != null) { 3050 r.createdConfig = new Configuration(mConfiguration); 3051 reportSizeConfigurations(r); 3052 if (!r.activity.mFinished && pendingActions != null) { 3053 pendingActions.setOldState(r.state); 3054 pendingActions.setRestoreInstanceState(true); 3055 pendingActions.setCallOnPostCreate(true); 3056 } 3057 } else { 3058 // If there was an error, for any reason, tell the activity manager to stop us. 3059 try { 3060 ActivityManager.getService() 3061 .finishActivity(r.token, Activity.RESULT_CANCELED, null, 3062 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 3063 } catch (RemoteException ex) { 3064 throw ex.rethrowFromSystemServer(); 3065 } 3066 } 3067 3068 return a; 3069 } 3070 3071 private void reportSizeConfigurations(ActivityClientRecord r) { 3072 Configuration[] configurations = r.activity.getResources().getSizeConfigurations(); 3073 if (configurations == null) { 3074 return; 3075 } 3076 SparseIntArray horizontal = new SparseIntArray(); 3077 SparseIntArray vertical = new SparseIntArray(); 3078 SparseIntArray smallest = new SparseIntArray(); 3079 for (int i = configurations.length - 1; i >= 0; i--) { 3080 Configuration config = configurations[i]; 3081 if (config.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { 3082 vertical.put(config.screenHeightDp, 0); 3083 } 3084 if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) { 3085 horizontal.put(config.screenWidthDp, 0); 3086 } 3087 if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { 3088 smallest.put(config.smallestScreenWidthDp, 0); 3089 } 3090 } 3091 try { 3092 ActivityManager.getService().reportSizeConfigurations(r.token, 3093 horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys()); 3094 } catch (RemoteException ex) { 3095 throw ex.rethrowFromSystemServer(); 3096 } 3097 3098 } 3099 3100 private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) { 3101 final int N = intents.size(); 3102 for (int i=0; i<N; i++) { 3103 ReferrerIntent intent = intents.get(i); 3104 intent.setExtrasClassLoader(r.activity.getClassLoader()); 3105 intent.prepareToEnterProcess(); 3106 r.activity.mFragments.noteStateNotSaved(); 3107 mInstrumentation.callActivityOnNewIntent(r.activity, intent); 3108 } 3109 } 3110 3111 void performNewIntents(IBinder token, List<ReferrerIntent> intents, boolean andPause) { 3112 final ActivityClientRecord r = mActivities.get(token); 3113 if (r == null) { 3114 return; 3115 } 3116 3117 final boolean resumed = !r.paused; 3118 if (resumed) { 3119 r.activity.mTemporaryPause = true; 3120 mInstrumentation.callActivityOnPause(r.activity); 3121 } 3122 checkAndBlockForNetworkAccess(); 3123 deliverNewIntents(r, intents); 3124 if (resumed) { 3125 r.activity.performResume(false, "performNewIntents"); 3126 r.activity.mTemporaryPause = false; 3127 } 3128 3129 if (r.paused && andPause) { 3130 // In this case the activity was in the paused state when we delivered the intent, 3131 // to guarantee onResume gets called after onNewIntent we temporarily resume the 3132 // activity and pause again as the caller wanted. 3133 performResumeActivity(token, false, "performNewIntents"); 3134 performPauseActivityIfNeeded(r, "performNewIntents"); 3135 } 3136 } 3137 3138 @Override 3139 public void handleNewIntent(IBinder token, List<ReferrerIntent> intents, boolean andPause) { 3140 performNewIntents(token, intents, andPause); 3141 } 3142 3143 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { 3144 // Filling for autofill has a few differences: 3145 // - it does not need an AssistContent 3146 // - it does not call onProvideAssistData() 3147 // - it needs an IAutoFillCallback 3148 boolean forAutofill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTOFILL; 3149 3150 // TODO: decide if lastSessionId logic applies to autofill sessions 3151 if (mLastSessionId != cmd.sessionId) { 3152 // Clear the existing structures 3153 mLastSessionId = cmd.sessionId; 3154 for (int i = mLastAssistStructures.size() - 1; i >= 0; i--) { 3155 AssistStructure structure = mLastAssistStructures.get(i).get(); 3156 if (structure != null) { 3157 structure.clearSendChannel(); 3158 } 3159 mLastAssistStructures.remove(i); 3160 } 3161 } 3162 3163 Bundle data = new Bundle(); 3164 AssistStructure structure = null; 3165 AssistContent content = forAutofill ? null : new AssistContent(); 3166 final long startTime = SystemClock.uptimeMillis(); 3167 ActivityClientRecord r = mActivities.get(cmd.activityToken); 3168 Uri referrer = null; 3169 if (r != null) { 3170 if (!forAutofill) { 3171 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data); 3172 r.activity.onProvideAssistData(data); 3173 referrer = r.activity.onProvideReferrer(); 3174 } 3175 if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutofill) { 3176 structure = new AssistStructure(r.activity, forAutofill, cmd.flags); 3177 Intent activityIntent = r.activity.getIntent(); 3178 boolean notSecure = r.window == null || 3179 (r.window.getAttributes().flags 3180 & WindowManager.LayoutParams.FLAG_SECURE) == 0; 3181 if (activityIntent != null && notSecure) { 3182 if (!forAutofill) { 3183 Intent intent = new Intent(activityIntent); 3184 intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION 3185 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)); 3186 intent.removeUnsafeExtras(); 3187 content.setDefaultIntent(intent); 3188 } 3189 } else { 3190 if (!forAutofill) { 3191 content.setDefaultIntent(new Intent()); 3192 } 3193 } 3194 if (!forAutofill) { 3195 r.activity.onProvideAssistContent(content); 3196 } 3197 } 3198 } 3199 if (structure == null) { 3200 structure = new AssistStructure(); 3201 } 3202 3203 // TODO: decide if lastSessionId logic applies to autofill sessions 3204 3205 structure.setAcquisitionStartTime(startTime); 3206 structure.setAcquisitionEndTime(SystemClock.uptimeMillis()); 3207 3208 mLastAssistStructures.add(new WeakReference<>(structure)); 3209 IActivityManager mgr = ActivityManager.getService(); 3210 try { 3211 mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer); 3212 } catch (RemoteException e) { 3213 throw e.rethrowFromSystemServer(); 3214 } 3215 } 3216 3217 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 3218 ActivityClientRecord r = mActivities.get(token); 3219 if (r != null) { 3220 r.activity.onTranslucentConversionComplete(drawComplete); 3221 } 3222 } 3223 3224 public void onNewActivityOptions(IBinder token, ActivityOptions options) { 3225 ActivityClientRecord r = mActivities.get(token); 3226 if (r != null) { 3227 r.activity.onNewActivityOptions(options); 3228 } 3229 } 3230 3231 public void handleInstallProvider(ProviderInfo info) { 3232 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3233 try { 3234 installContentProviders(mInitialApplication, Arrays.asList(info)); 3235 } finally { 3236 StrictMode.setThreadPolicy(oldPolicy); 3237 } 3238 } 3239 3240 private void handleEnterAnimationComplete(IBinder token) { 3241 ActivityClientRecord r = mActivities.get(token); 3242 if (r != null) { 3243 r.activity.dispatchEnterAnimationComplete(); 3244 } 3245 } 3246 3247 private void handleStartBinderTracking() { 3248 Binder.enableTracing(); 3249 } 3250 3251 private void handleStopBinderTrackingAndDump(ParcelFileDescriptor fd) { 3252 try { 3253 Binder.disableTracing(); 3254 Binder.getTransactionTracker().writeTracesToFile(fd); 3255 } finally { 3256 IoUtils.closeQuietly(fd); 3257 Binder.getTransactionTracker().clearTraces(); 3258 } 3259 } 3260 3261 @Override 3262 public void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode, 3263 Configuration overrideConfig) { 3264 final ActivityClientRecord r = mActivities.get(token); 3265 if (r != null) { 3266 final Configuration newConfig = new Configuration(mConfiguration); 3267 if (overrideConfig != null) { 3268 newConfig.updateFrom(overrideConfig); 3269 } 3270 r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig); 3271 } 3272 } 3273 3274 @Override 3275 public void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode, 3276 Configuration overrideConfig) { 3277 final ActivityClientRecord r = mActivities.get(token); 3278 if (r != null) { 3279 final Configuration newConfig = new Configuration(mConfiguration); 3280 if (overrideConfig != null) { 3281 newConfig.updateFrom(overrideConfig); 3282 } 3283 r.activity.dispatchPictureInPictureModeChanged(isInPipMode, newConfig); 3284 } 3285 } 3286 3287 private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) { 3288 final ActivityClientRecord r = mActivities.get(token); 3289 if (r != null) { 3290 r.voiceInteractor = interactor; 3291 r.activity.setVoiceInteractor(interactor); 3292 if (interactor == null) { 3293 r.activity.onLocalVoiceInteractionStopped(); 3294 } else { 3295 r.activity.onLocalVoiceInteractionStarted(); 3296 } 3297 } 3298 } 3299 3300 private static boolean attemptAttachAgent(String agent, ClassLoader classLoader) { 3301 try { 3302 VMDebug.attachAgent(agent, classLoader); 3303 return true; 3304 } catch (IOException e) { 3305 Slog.e(TAG, "Attaching agent with " + classLoader + " failed: " + agent); 3306 return false; 3307 } 3308 } 3309 3310 static void handleAttachAgent(String agent, LoadedApk loadedApk) { 3311 ClassLoader classLoader = loadedApk != null ? loadedApk.getClassLoader() : null; 3312 if (attemptAttachAgent(agent, classLoader)) { 3313 return; 3314 } 3315 if (classLoader != null) { 3316 attemptAttachAgent(agent, null); 3317 } 3318 } 3319 3320 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); 3321 3322 /** 3323 * Return the Intent that's currently being handled by a 3324 * BroadcastReceiver on this thread, or null if none. 3325 * @hide 3326 */ 3327 public static Intent getIntentBeingBroadcast() { 3328 return sCurrentBroadcastIntent.get(); 3329 } 3330 3331 private void handleReceiver(ReceiverData data) { 3332 // If we are getting ready to gc after going to the background, well 3333 // we are back active so skip it. 3334 unscheduleGcIdler(); 3335 3336 String component = data.intent.getComponent().getClassName(); 3337 3338 LoadedApk packageInfo = getPackageInfoNoCheck( 3339 data.info.applicationInfo, data.compatInfo); 3340 3341 IActivityManager mgr = ActivityManager.getService(); 3342 3343 Application app; 3344 BroadcastReceiver receiver; 3345 ContextImpl context; 3346 try { 3347 app = packageInfo.makeApplication(false, mInstrumentation); 3348 context = (ContextImpl) app.getBaseContext(); 3349 if (data.info.splitName != null) { 3350 context = (ContextImpl) context.createContextForSplit(data.info.splitName); 3351 } 3352 java.lang.ClassLoader cl = context.getClassLoader(); 3353 data.intent.setExtrasClassLoader(cl); 3354 data.intent.prepareToEnterProcess(); 3355 data.setExtrasClassLoader(cl); 3356 receiver = packageInfo.getAppFactory() 3357 .instantiateReceiver(cl, data.info.name, data.intent); 3358 } catch (Exception e) { 3359 if (DEBUG_BROADCAST) Slog.i(TAG, 3360 "Finishing failed broadcast to " + data.intent.getComponent()); 3361 data.sendFinished(mgr); 3362 throw new RuntimeException( 3363 "Unable to instantiate receiver " + component 3364 + ": " + e.toString(), e); 3365 } 3366 3367 try { 3368 if (localLOGV) Slog.v( 3369 TAG, "Performing receive of " + data.intent 3370 + ": app=" + app 3371 + ", appName=" + app.getPackageName() 3372 + ", pkg=" + packageInfo.getPackageName() 3373 + ", comp=" + data.intent.getComponent().toShortString() 3374 + ", dir=" + packageInfo.getAppDir()); 3375 3376 sCurrentBroadcastIntent.set(data.intent); 3377 receiver.setPendingResult(data); 3378 receiver.onReceive(context.getReceiverRestrictedContext(), 3379 data.intent); 3380 } catch (Exception e) { 3381 if (DEBUG_BROADCAST) Slog.i(TAG, 3382 "Finishing failed broadcast to " + data.intent.getComponent()); 3383 data.sendFinished(mgr); 3384 if (!mInstrumentation.onException(receiver, e)) { 3385 throw new RuntimeException( 3386 "Unable to start receiver " + component 3387 + ": " + e.toString(), e); 3388 } 3389 } finally { 3390 sCurrentBroadcastIntent.set(null); 3391 } 3392 3393 if (receiver.getPendingResult() != null) { 3394 data.finish(); 3395 } 3396 } 3397 3398 // Instantiate a BackupAgent and tell it that it's alive 3399 private void handleCreateBackupAgent(CreateBackupAgentData data) { 3400 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); 3401 3402 // Sanity check the requested target package's uid against ours 3403 try { 3404 PackageInfo requestedPackage = getPackageManager().getPackageInfo( 3405 data.appInfo.packageName, 0, UserHandle.myUserId()); 3406 if (requestedPackage.applicationInfo.uid != Process.myUid()) { 3407 Slog.w(TAG, "Asked to instantiate non-matching package " 3408 + data.appInfo.packageName); 3409 return; 3410 } 3411 } catch (RemoteException e) { 3412 throw e.rethrowFromSystemServer(); 3413 } 3414 3415 // no longer idle; we have backup work to do 3416 unscheduleGcIdler(); 3417 3418 // instantiate the BackupAgent class named in the manifest 3419 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 3420 String packageName = packageInfo.mPackageName; 3421 if (packageName == null) { 3422 Slog.d(TAG, "Asked to create backup agent for nonexistent package"); 3423 return; 3424 } 3425 3426 String classname = data.appInfo.backupAgentName; 3427 // full backup operation but no app-supplied agent? use the default implementation 3428 if (classname == null && (data.backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL 3429 || data.backupMode == ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL)) { 3430 classname = "android.app.backup.FullBackupAgent"; 3431 } 3432 3433 try { 3434 IBinder binder = null; 3435 BackupAgent agent = mBackupAgents.get(packageName); 3436 if (agent != null) { 3437 // reusing the existing instance 3438 if (DEBUG_BACKUP) { 3439 Slog.v(TAG, "Reusing existing agent instance"); 3440 } 3441 binder = agent.onBind(); 3442 } else { 3443 try { 3444 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname); 3445 3446 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 3447 agent = (BackupAgent) cl.loadClass(classname).newInstance(); 3448 3449 // set up the agent's context 3450 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 3451 context.setOuterContext(agent); 3452 agent.attach(context); 3453 3454 agent.onCreate(); 3455 binder = agent.onBind(); 3456 mBackupAgents.put(packageName, agent); 3457 } catch (Exception e) { 3458 // If this is during restore, fail silently; otherwise go 3459 // ahead and let the user see the crash. 3460 Slog.e(TAG, "Agent threw during creation: " + e); 3461 if (data.backupMode != ApplicationThreadConstants.BACKUP_MODE_RESTORE 3462 && data.backupMode != 3463 ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL) { 3464 throw e; 3465 } 3466 // falling through with 'binder' still null 3467 } 3468 } 3469 3470 // tell the OS that we're live now 3471 try { 3472 ActivityManager.getService().backupAgentCreated(packageName, binder); 3473 } catch (RemoteException e) { 3474 throw e.rethrowFromSystemServer(); 3475 } 3476 } catch (Exception e) { 3477 throw new RuntimeException("Unable to create BackupAgent " 3478 + classname + ": " + e.toString(), e); 3479 } 3480 } 3481 3482 // Tear down a BackupAgent 3483 private void handleDestroyBackupAgent(CreateBackupAgentData data) { 3484 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data); 3485 3486 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 3487 String packageName = packageInfo.mPackageName; 3488 BackupAgent agent = mBackupAgents.get(packageName); 3489 if (agent != null) { 3490 try { 3491 agent.onDestroy(); 3492 } catch (Exception e) { 3493 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo); 3494 e.printStackTrace(); 3495 } 3496 mBackupAgents.remove(packageName); 3497 } else { 3498 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data); 3499 } 3500 } 3501 3502 private void handleCreateService(CreateServiceData data) { 3503 // If we are getting ready to gc after going to the background, well 3504 // we are back active so skip it. 3505 unscheduleGcIdler(); 3506 3507 LoadedApk packageInfo = getPackageInfoNoCheck( 3508 data.info.applicationInfo, data.compatInfo); 3509 Service service = null; 3510 try { 3511 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 3512 service = packageInfo.getAppFactory() 3513 .instantiateService(cl, data.info.name, data.intent); 3514 } catch (Exception e) { 3515 if (!mInstrumentation.onException(service, e)) { 3516 throw new RuntimeException( 3517 "Unable to instantiate service " + data.info.name 3518 + ": " + e.toString(), e); 3519 } 3520 } 3521 3522 try { 3523 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 3524 3525 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 3526 context.setOuterContext(service); 3527 3528 Application app = packageInfo.makeApplication(false, mInstrumentation); 3529 service.attach(context, this, data.info.name, data.token, app, 3530 ActivityManager.getService()); 3531 service.onCreate(); 3532 mServices.put(data.token, service); 3533 try { 3534 ActivityManager.getService().serviceDoneExecuting( 3535 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3536 } catch (RemoteException e) { 3537 throw e.rethrowFromSystemServer(); 3538 } 3539 } catch (Exception e) { 3540 if (!mInstrumentation.onException(service, e)) { 3541 throw new RuntimeException( 3542 "Unable to create service " + data.info.name 3543 + ": " + e.toString(), e); 3544 } 3545 } 3546 } 3547 3548 private void handleBindService(BindServiceData data) { 3549 Service s = mServices.get(data.token); 3550 if (DEBUG_SERVICE) 3551 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); 3552 if (s != null) { 3553 try { 3554 data.intent.setExtrasClassLoader(s.getClassLoader()); 3555 data.intent.prepareToEnterProcess(); 3556 try { 3557 if (!data.rebind) { 3558 IBinder binder = s.onBind(data.intent); 3559 ActivityManager.getService().publishService( 3560 data.token, data.intent, binder); 3561 } else { 3562 s.onRebind(data.intent); 3563 ActivityManager.getService().serviceDoneExecuting( 3564 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3565 } 3566 ensureJitEnabled(); 3567 } catch (RemoteException ex) { 3568 throw ex.rethrowFromSystemServer(); 3569 } 3570 } catch (Exception e) { 3571 if (!mInstrumentation.onException(s, e)) { 3572 throw new RuntimeException( 3573 "Unable to bind to service " + s 3574 + " with " + data.intent + ": " + e.toString(), e); 3575 } 3576 } 3577 } 3578 } 3579 3580 private void handleUnbindService(BindServiceData data) { 3581 Service s = mServices.get(data.token); 3582 if (s != null) { 3583 try { 3584 data.intent.setExtrasClassLoader(s.getClassLoader()); 3585 data.intent.prepareToEnterProcess(); 3586 boolean doRebind = s.onUnbind(data.intent); 3587 try { 3588 if (doRebind) { 3589 ActivityManager.getService().unbindFinished( 3590 data.token, data.intent, doRebind); 3591 } else { 3592 ActivityManager.getService().serviceDoneExecuting( 3593 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3594 } 3595 } catch (RemoteException ex) { 3596 throw ex.rethrowFromSystemServer(); 3597 } 3598 } catch (Exception e) { 3599 if (!mInstrumentation.onException(s, e)) { 3600 throw new RuntimeException( 3601 "Unable to unbind to service " + s 3602 + " with " + data.intent + ": " + e.toString(), e); 3603 } 3604 } 3605 } 3606 } 3607 3608 private void handleDumpService(DumpComponentInfo info) { 3609 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3610 try { 3611 Service s = mServices.get(info.token); 3612 if (s != null) { 3613 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 3614 info.fd.getFileDescriptor())); 3615 s.dump(info.fd.getFileDescriptor(), pw, info.args); 3616 pw.flush(); 3617 } 3618 } finally { 3619 IoUtils.closeQuietly(info.fd); 3620 StrictMode.setThreadPolicy(oldPolicy); 3621 } 3622 } 3623 3624 private void handleDumpActivity(DumpComponentInfo info) { 3625 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3626 try { 3627 ActivityClientRecord r = mActivities.get(info.token); 3628 if (r != null && r.activity != null) { 3629 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 3630 info.fd.getFileDescriptor())); 3631 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); 3632 pw.flush(); 3633 } 3634 } finally { 3635 IoUtils.closeQuietly(info.fd); 3636 StrictMode.setThreadPolicy(oldPolicy); 3637 } 3638 } 3639 3640 private void handleDumpProvider(DumpComponentInfo info) { 3641 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3642 try { 3643 ProviderClientRecord r = mLocalProviders.get(info.token); 3644 if (r != null && r.mLocalProvider != null) { 3645 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 3646 info.fd.getFileDescriptor())); 3647 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args); 3648 pw.flush(); 3649 } 3650 } finally { 3651 IoUtils.closeQuietly(info.fd); 3652 StrictMode.setThreadPolicy(oldPolicy); 3653 } 3654 } 3655 3656 private void handleServiceArgs(ServiceArgsData data) { 3657 Service s = mServices.get(data.token); 3658 if (s != null) { 3659 try { 3660 if (data.args != null) { 3661 data.args.setExtrasClassLoader(s.getClassLoader()); 3662 data.args.prepareToEnterProcess(); 3663 } 3664 int res; 3665 if (!data.taskRemoved) { 3666 res = s.onStartCommand(data.args, data.flags, data.startId); 3667 } else { 3668 s.onTaskRemoved(data.args); 3669 res = Service.START_TASK_REMOVED_COMPLETE; 3670 } 3671 3672 QueuedWork.waitToFinish(); 3673 3674 try { 3675 ActivityManager.getService().serviceDoneExecuting( 3676 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); 3677 } catch (RemoteException e) { 3678 throw e.rethrowFromSystemServer(); 3679 } 3680 ensureJitEnabled(); 3681 } catch (Exception e) { 3682 if (!mInstrumentation.onException(s, e)) { 3683 throw new RuntimeException( 3684 "Unable to start service " + s 3685 + " with " + data.args + ": " + e.toString(), e); 3686 } 3687 } 3688 } 3689 } 3690 3691 private void handleStopService(IBinder token) { 3692 Service s = mServices.remove(token); 3693 if (s != null) { 3694 try { 3695 if (localLOGV) Slog.v(TAG, "Destroying service " + s); 3696 s.onDestroy(); 3697 s.detachAndCleanUp(); 3698 Context context = s.getBaseContext(); 3699 if (context instanceof ContextImpl) { 3700 final String who = s.getClassName(); 3701 ((ContextImpl) context).scheduleFinalCleanup(who, "Service"); 3702 } 3703 3704 QueuedWork.waitToFinish(); 3705 3706 try { 3707 ActivityManager.getService().serviceDoneExecuting( 3708 token, SERVICE_DONE_EXECUTING_STOP, 0, 0); 3709 } catch (RemoteException e) { 3710 throw e.rethrowFromSystemServer(); 3711 } 3712 } catch (Exception e) { 3713 if (!mInstrumentation.onException(s, e)) { 3714 throw new RuntimeException( 3715 "Unable to stop service " + s 3716 + ": " + e.toString(), e); 3717 } 3718 Slog.i(TAG, "handleStopService: exception for " + token, e); 3719 } 3720 } else { 3721 Slog.i(TAG, "handleStopService: token=" + token + " not found."); 3722 } 3723 //Slog.i(TAG, "Running services: " + mServices); 3724 } 3725 3726 ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest, 3727 String reason) { 3728 ActivityClientRecord r = mActivities.get(token); 3729 if (localLOGV) Slog.v(TAG, "Performing resume of " + r 3730 + " finished=" + r.activity.mFinished); 3731 if (r != null && !r.activity.mFinished) { 3732 if (r.getLifecycleState() == ON_RESUME) { 3733 if (!finalStateRequest) { 3734 final RuntimeException e = new IllegalStateException( 3735 "Trying to resume activity which is already resumed"); 3736 Slog.e(TAG, e.getMessage(), e); 3737 Slog.e(TAG, r.getStateString()); 3738 // TODO(lifecycler): A double resume request is possible when an activity 3739 // receives two consequent transactions with relaunch requests and "resumed" 3740 // final state requests and the second relaunch is omitted. We still try to 3741 // handle two resume requests for the final state. For cases other than this 3742 // one, we don't expect it to happen. 3743 } 3744 return null; 3745 } 3746 if (finalStateRequest) { 3747 r.hideForNow = false; 3748 r.activity.mStartedActivity = false; 3749 } 3750 try { 3751 r.activity.onStateNotSaved(); 3752 r.activity.mFragments.noteStateNotSaved(); 3753 checkAndBlockForNetworkAccess(); 3754 if (r.pendingIntents != null) { 3755 deliverNewIntents(r, r.pendingIntents); 3756 r.pendingIntents = null; 3757 } 3758 if (r.pendingResults != null) { 3759 deliverResults(r, r.pendingResults); 3760 r.pendingResults = null; 3761 } 3762 r.activity.performResume(r.startsNotResumed, reason); 3763 3764 r.state = null; 3765 r.persistentState = null; 3766 r.setState(ON_RESUME); 3767 } catch (Exception e) { 3768 if (!mInstrumentation.onException(r.activity, e)) { 3769 throw new RuntimeException( 3770 "Unable to resume activity " 3771 + r.intent.getComponent().toShortString() 3772 + ": " + e.toString(), e); 3773 } 3774 } 3775 } 3776 return r; 3777 } 3778 3779 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) { 3780 if (r.mPreserveWindow && !force) { 3781 return; 3782 } 3783 if (r.mPendingRemoveWindow != null) { 3784 r.mPendingRemoveWindowManager.removeViewImmediate( 3785 r.mPendingRemoveWindow.getDecorView()); 3786 IBinder wtoken = r.mPendingRemoveWindow.getDecorView().getWindowToken(); 3787 if (wtoken != null) { 3788 WindowManagerGlobal.getInstance().closeAll(wtoken, 3789 r.activity.getClass().getName(), "Activity"); 3790 } 3791 } 3792 r.mPendingRemoveWindow = null; 3793 r.mPendingRemoveWindowManager = null; 3794 } 3795 3796 @Override 3797 public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, 3798 String reason) { 3799 // If we are getting ready to gc after going to the background, well 3800 // we are back active so skip it. 3801 unscheduleGcIdler(); 3802 mSomeActivitiesChanged = true; 3803 3804 // TODO Push resumeArgs into the activity for consideration 3805 final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason); 3806 3807 if (r != null) { 3808 final Activity a = r.activity; 3809 3810 if (localLOGV) Slog.v( 3811 TAG, "Resume " + r + " started activity: " + 3812 a.mStartedActivity + ", hideForNow: " + r.hideForNow 3813 + ", finished: " + a.mFinished); 3814 3815 final int forwardBit = isForward ? 3816 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 3817 3818 // If the window hasn't yet been added to the window manager, 3819 // and this guy didn't finish itself or start another activity, 3820 // then go ahead and add the window. 3821 boolean willBeVisible = !a.mStartedActivity; 3822 if (!willBeVisible) { 3823 try { 3824 willBeVisible = ActivityManager.getService().willActivityBeVisible( 3825 a.getActivityToken()); 3826 } catch (RemoteException e) { 3827 throw e.rethrowFromSystemServer(); 3828 } 3829 } 3830 if (r.window == null && !a.mFinished && willBeVisible) { 3831 r.window = r.activity.getWindow(); 3832 View decor = r.window.getDecorView(); 3833 decor.setVisibility(View.INVISIBLE); 3834 ViewManager wm = a.getWindowManager(); 3835 WindowManager.LayoutParams l = r.window.getAttributes(); 3836 a.mDecor = decor; 3837 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 3838 l.softInputMode |= forwardBit; 3839 if (r.mPreserveWindow) { 3840 a.mWindowAdded = true; 3841 r.mPreserveWindow = false; 3842 // Normally the ViewRoot sets up callbacks with the Activity 3843 // in addView->ViewRootImpl#setView. If we are instead reusing 3844 // the decor view we have to notify the view root that the 3845 // callbacks may have changed. 3846 ViewRootImpl impl = decor.getViewRootImpl(); 3847 if (impl != null) { 3848 impl.notifyChildRebuilt(); 3849 } 3850 } 3851 if (a.mVisibleFromClient) { 3852 if (!a.mWindowAdded) { 3853 a.mWindowAdded = true; 3854 wm.addView(decor, l); 3855 } else { 3856 // The activity will get a callback for this {@link LayoutParams} change 3857 // earlier. However, at that time the decor will not be set (this is set 3858 // in this method), so no action will be taken. This call ensures the 3859 // callback occurs with the decor set. 3860 a.onWindowAttributesChanged(l); 3861 } 3862 } 3863 3864 // If the window has already been added, but during resume 3865 // we started another activity, then don't yet make the 3866 // window visible. 3867 } else if (!willBeVisible) { 3868 if (localLOGV) Slog.v( 3869 TAG, "Launch " + r + " mStartedActivity set"); 3870 r.hideForNow = true; 3871 } 3872 3873 // Get rid of anything left hanging around. 3874 cleanUpPendingRemoveWindows(r, false /* force */); 3875 3876 // The window is now visible if it has been added, we are not 3877 // simply finishing, and we are not starting another activity. 3878 if (!r.activity.mFinished && willBeVisible 3879 && r.activity.mDecor != null && !r.hideForNow) { 3880 if (r.newConfig != null) { 3881 performConfigurationChangedForActivity(r, r.newConfig); 3882 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 3883 + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig); 3884 r.newConfig = null; 3885 } 3886 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 3887 + isForward); 3888 WindowManager.LayoutParams l = r.window.getAttributes(); 3889 if ((l.softInputMode 3890 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 3891 != forwardBit) { 3892 l.softInputMode = (l.softInputMode 3893 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 3894 | forwardBit; 3895 if (r.activity.mVisibleFromClient) { 3896 ViewManager wm = a.getWindowManager(); 3897 View decor = r.window.getDecorView(); 3898 wm.updateViewLayout(decor, l); 3899 } 3900 } 3901 3902 r.activity.mVisibleFromServer = true; 3903 mNumVisibleActivities++; 3904 if (r.activity.mVisibleFromClient) { 3905 r.activity.makeVisible(); 3906 } 3907 } 3908 3909 r.nextIdle = mNewActivities; 3910 mNewActivities = r; 3911 if (localLOGV) { 3912 Slog.v(TAG, "Scheduling idle handler for " + r); 3913 } 3914 Looper.myQueue().addIdleHandler(new Idler()); 3915 } else { 3916 // If an exception was thrown when trying to resume, then 3917 // just end this activity. 3918 try { 3919 ActivityManager.getService() 3920 .finishActivity(token, Activity.RESULT_CANCELED, null, 3921 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 3922 } catch (RemoteException ex) { 3923 throw ex.rethrowFromSystemServer(); 3924 } 3925 } 3926 } 3927 3928 @Override 3929 public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, 3930 int configChanges, PendingTransactionActions pendingActions, String reason) { 3931 ActivityClientRecord r = mActivities.get(token); 3932 if (r != null) { 3933 if (userLeaving) { 3934 performUserLeavingActivity(r); 3935 } 3936 3937 r.activity.mConfigChangeFlags |= configChanges; 3938 performPauseActivity(r, finished, reason, pendingActions); 3939 3940 // Make sure any pending writes are now committed. 3941 if (r.isPreHoneycomb()) { 3942 QueuedWork.waitToFinish(); 3943 } 3944 mSomeActivitiesChanged = true; 3945 } 3946 } 3947 3948 final void performUserLeavingActivity(ActivityClientRecord r) { 3949 mInstrumentation.callActivityOnUserLeaving(r.activity); 3950 } 3951 3952 final Bundle performPauseActivity(IBinder token, boolean finished, String reason, 3953 PendingTransactionActions pendingActions) { 3954 ActivityClientRecord r = mActivities.get(token); 3955 return r != null ? performPauseActivity(r, finished, reason, pendingActions) : null; 3956 } 3957 3958 /** 3959 * Pause the activity. 3960 * @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise. 3961 */ 3962 private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason, 3963 PendingTransactionActions pendingActions) { 3964 if (r.paused) { 3965 if (r.activity.mFinished) { 3966 // If we are finishing, we won't call onResume() in certain cases. 3967 // So here we likewise don't want to call onPause() if the activity 3968 // isn't resumed. 3969 return null; 3970 } 3971 RuntimeException e = new RuntimeException( 3972 "Performing pause of activity that is not resumed: " 3973 + r.intent.getComponent().toShortString()); 3974 Slog.e(TAG, e.getMessage(), e); 3975 } 3976 if (finished) { 3977 r.activity.mFinished = true; 3978 } 3979 3980 // Pre-Honeycomb apps always save their state before pausing 3981 final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb(); 3982 if (shouldSaveState) { 3983 callActivityOnSaveInstanceState(r); 3984 } 3985 3986 performPauseActivityIfNeeded(r, reason); 3987 3988 // Notify any outstanding on paused listeners 3989 ArrayList<OnActivityPausedListener> listeners; 3990 synchronized (mOnPauseListeners) { 3991 listeners = mOnPauseListeners.remove(r.activity); 3992 } 3993 int size = (listeners != null ? listeners.size() : 0); 3994 for (int i = 0; i < size; i++) { 3995 listeners.get(i).onPaused(r.activity); 3996 } 3997 3998 final Bundle oldState = pendingActions != null ? pendingActions.getOldState() : null; 3999 if (oldState != null) { 4000 // We need to keep around the original state, in case we need to be created again. 4001 // But we only do this for pre-Honeycomb apps, which always save their state when 4002 // pausing, so we can not have them save their state when restarting from a paused 4003 // state. For HC and later, we want to (and can) let the state be saved as the 4004 // normal part of stopping the activity. 4005 if (r.isPreHoneycomb()) { 4006 r.state = oldState; 4007 } 4008 } 4009 4010 return shouldSaveState ? r.state : null; 4011 } 4012 4013 private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) { 4014 if (r.paused) { 4015 // You are already paused silly... 4016 return; 4017 } 4018 4019 try { 4020 r.activity.mCalled = false; 4021 mInstrumentation.callActivityOnPause(r.activity); 4022 if (!r.activity.mCalled) { 4023 throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent) 4024 + " did not call through to super.onPause()"); 4025 } 4026 } catch (SuperNotCalledException e) { 4027 throw e; 4028 } catch (Exception e) { 4029 if (!mInstrumentation.onException(r.activity, e)) { 4030 throw new RuntimeException("Unable to pause activity " 4031 + safeToComponentShortString(r.intent) + ": " + e.toString(), e); 4032 } 4033 } 4034 r.setState(ON_PAUSE); 4035 } 4036 4037 final void performStopActivity(IBinder token, boolean saveState, String reason) { 4038 ActivityClientRecord r = mActivities.get(token); 4039 performStopActivityInner(r, null, false, saveState, reason); 4040 } 4041 4042 private static final class ProviderRefCount { 4043 public final ContentProviderHolder holder; 4044 public final ProviderClientRecord client; 4045 public int stableCount; 4046 public int unstableCount; 4047 4048 // When this is set, the stable and unstable ref counts are 0 and 4049 // we have a pending operation scheduled to remove the ref count 4050 // from the activity manager. On the activity manager we are still 4051 // holding an unstable ref, though it is not reflected in the counts 4052 // here. 4053 public boolean removePending; 4054 4055 ProviderRefCount(ContentProviderHolder inHolder, 4056 ProviderClientRecord inClient, int sCount, int uCount) { 4057 holder = inHolder; 4058 client = inClient; 4059 stableCount = sCount; 4060 unstableCount = uCount; 4061 } 4062 } 4063 4064 /** 4065 * Core implementation of stopping an activity. Note this is a little 4066 * tricky because the server's meaning of stop is slightly different 4067 * than our client -- for the server, stop means to save state and give 4068 * it the result when it is done, but the window may still be visible. 4069 * For the client, we want to call onStop()/onStart() to indicate when 4070 * the activity's UI visibility changes. 4071 */ 4072 private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown, 4073 boolean saveState, String reason) { 4074 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 4075 if (r != null) { 4076 if (!keepShown && r.stopped) { 4077 if (r.activity.mFinished) { 4078 // If we are finishing, we won't call onResume() in certain 4079 // cases. So here we likewise don't want to call onStop() 4080 // if the activity isn't resumed. 4081 return; 4082 } 4083 RuntimeException e = new RuntimeException( 4084 "Performing stop of activity that is already stopped: " 4085 + r.intent.getComponent().toShortString()); 4086 Slog.e(TAG, e.getMessage(), e); 4087 Slog.e(TAG, r.getStateString()); 4088 } 4089 4090 // One must first be paused before stopped... 4091 performPauseActivityIfNeeded(r, reason); 4092 4093 if (info != null) { 4094 try { 4095 // First create a thumbnail for the activity... 4096 // For now, don't create the thumbnail here; we are 4097 // doing that by doing a screen snapshot. 4098 info.setDescription(r.activity.onCreateDescription()); 4099 } catch (Exception e) { 4100 if (!mInstrumentation.onException(r.activity, e)) { 4101 throw new RuntimeException( 4102 "Unable to save state of activity " 4103 + r.intent.getComponent().toShortString() 4104 + ": " + e.toString(), e); 4105 } 4106 } 4107 } 4108 4109 if (!keepShown) { 4110 callActivityOnStop(r, saveState, reason); 4111 } 4112 } 4113 } 4114 4115 /** 4116 * Calls {@link Activity#onStop()} and {@link Activity#onSaveInstanceState(Bundle)}, and updates 4117 * the client record's state. 4118 * All calls to stop an activity must be done through this method to make sure that 4119 * {@link Activity#onSaveInstanceState(Bundle)} is also executed in the same call. 4120 */ 4121 private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) { 4122 // Before P onSaveInstanceState was called before onStop, starting with P it's 4123 // called after. Before Honeycomb state was always saved before onPause. 4124 final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null 4125 && !r.isPreHoneycomb(); 4126 final boolean isPreP = r.isPreP(); 4127 if (shouldSaveState && isPreP) { 4128 callActivityOnSaveInstanceState(r); 4129 } 4130 4131 try { 4132 r.activity.performStop(false /*preserveWindow*/, reason); 4133 } catch (SuperNotCalledException e) { 4134 throw e; 4135 } catch (Exception e) { 4136 if (!mInstrumentation.onException(r.activity, e)) { 4137 throw new RuntimeException( 4138 "Unable to stop activity " 4139 + r.intent.getComponent().toShortString() 4140 + ": " + e.toString(), e); 4141 } 4142 } 4143 r.setState(ON_STOP); 4144 4145 if (shouldSaveState && !isPreP) { 4146 callActivityOnSaveInstanceState(r); 4147 } 4148 } 4149 4150 private void updateVisibility(ActivityClientRecord r, boolean show) { 4151 View v = r.activity.mDecor; 4152 if (v != null) { 4153 if (show) { 4154 if (!r.activity.mVisibleFromServer) { 4155 r.activity.mVisibleFromServer = true; 4156 mNumVisibleActivities++; 4157 if (r.activity.mVisibleFromClient) { 4158 r.activity.makeVisible(); 4159 } 4160 } 4161 if (r.newConfig != null) { 4162 performConfigurationChangedForActivity(r, r.newConfig); 4163 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 4164 + r.activityInfo.name + " with new config " 4165 + r.activity.mCurrentConfig); 4166 r.newConfig = null; 4167 } 4168 } else { 4169 if (r.activity.mVisibleFromServer) { 4170 r.activity.mVisibleFromServer = false; 4171 mNumVisibleActivities--; 4172 v.setVisibility(View.INVISIBLE); 4173 } 4174 } 4175 } 4176 } 4177 4178 @Override 4179 public void handleStopActivity(IBinder token, boolean show, int configChanges, 4180 PendingTransactionActions pendingActions, String reason) { 4181 final ActivityClientRecord r = mActivities.get(token); 4182 r.activity.mConfigChangeFlags |= configChanges; 4183 4184 final StopInfo stopInfo = new StopInfo(); 4185 performStopActivityInner(r, stopInfo, show, true, reason); 4186 4187 if (localLOGV) Slog.v( 4188 TAG, "Finishing stop of " + r + ": show=" + show 4189 + " win=" + r.window); 4190 4191 updateVisibility(r, show); 4192 4193 // Make sure any pending writes are now committed. 4194 if (!r.isPreHoneycomb()) { 4195 QueuedWork.waitToFinish(); 4196 } 4197 4198 stopInfo.setActivity(r); 4199 stopInfo.setState(r.state); 4200 stopInfo.setPersistentState(r.persistentState); 4201 pendingActions.setStopInfo(stopInfo); 4202 mSomeActivitiesChanged = true; 4203 } 4204 4205 /** 4206 * Schedule the call to tell the activity manager we have stopped. We don't do this 4207 * immediately, because we want to have a chance for any other pending work (in particular 4208 * memory trim requests) to complete before you tell the activity manager to proceed and allow 4209 * us to go fully into the background. 4210 */ 4211 @Override 4212 public void reportStop(PendingTransactionActions pendingActions) { 4213 mH.post(pendingActions.getStopInfo()); 4214 } 4215 4216 @Override 4217 public void performRestartActivity(IBinder token, boolean start) { 4218 ActivityClientRecord r = mActivities.get(token); 4219 if (r.stopped) { 4220 r.activity.performRestart(start, "performRestartActivity"); 4221 if (start) { 4222 r.setState(ON_START); 4223 } 4224 } 4225 } 4226 4227 @Override 4228 public void handleWindowVisibility(IBinder token, boolean show) { 4229 ActivityClientRecord r = mActivities.get(token); 4230 4231 if (r == null) { 4232 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 4233 return; 4234 } 4235 4236 if (!show && !r.stopped) { 4237 performStopActivityInner(r, null, show, false, "handleWindowVisibility"); 4238 } else if (show && r.stopped) { 4239 // If we are getting ready to gc after going to the background, well 4240 // we are back active so skip it. 4241 unscheduleGcIdler(); 4242 4243 r.activity.performRestart(true /* start */, "handleWindowVisibility"); 4244 r.setState(ON_START); 4245 } 4246 if (r.activity.mDecor != null) { 4247 if (false) Slog.v( 4248 TAG, "Handle window " + r + " visibility: " + show); 4249 updateVisibility(r, show); 4250 } 4251 mSomeActivitiesChanged = true; 4252 } 4253 4254 // TODO: This method should be changed to use {@link #performStopActivityInner} to perform to 4255 // stop operation on the activity to reduce code duplication and the chance of fixing a bug in 4256 // one place and missing the other. 4257 private void handleSleeping(IBinder token, boolean sleeping) { 4258 ActivityClientRecord r = mActivities.get(token); 4259 4260 if (r == null) { 4261 Log.w(TAG, "handleSleeping: no activity for token " + token); 4262 return; 4263 } 4264 4265 if (sleeping) { 4266 if (!r.stopped && !r.isPreHoneycomb()) { 4267 callActivityOnStop(r, true /* saveState */, "sleeping"); 4268 } 4269 4270 // Make sure any pending writes are now committed. 4271 if (!r.isPreHoneycomb()) { 4272 QueuedWork.waitToFinish(); 4273 } 4274 4275 // Tell activity manager we slept. 4276 try { 4277 ActivityManager.getService().activitySlept(r.token); 4278 } catch (RemoteException ex) { 4279 throw ex.rethrowFromSystemServer(); 4280 } 4281 } else { 4282 if (r.stopped && r.activity.mVisibleFromServer) { 4283 r.activity.performRestart(true /* start */, "handleSleeping"); 4284 r.setState(ON_START); 4285 } 4286 } 4287 } 4288 4289 private void handleSetCoreSettings(Bundle coreSettings) { 4290 synchronized (mResourcesManager) { 4291 mCoreSettings = coreSettings; 4292 } 4293 onCoreSettingsChange(); 4294 } 4295 4296 private void onCoreSettingsChange() { 4297 boolean debugViewAttributes = 4298 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 4299 if (debugViewAttributes != View.mDebugViewAttributes) { 4300 View.mDebugViewAttributes = debugViewAttributes; 4301 4302 // request all activities to relaunch for the changes to take place 4303 relaunchAllActivities(); 4304 } 4305 } 4306 4307 private void relaunchAllActivities() { 4308 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { 4309 final Activity activity = entry.getValue().activity; 4310 if (!activity.mFinished) { 4311 handleRelaunchActivityLocally(entry.getKey()); 4312 } 4313 } 4314 } 4315 4316 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 4317 LoadedApk apk = peekPackageInfo(data.pkg, false); 4318 if (apk != null) { 4319 apk.setCompatibilityInfo(data.info); 4320 } 4321 apk = peekPackageInfo(data.pkg, true); 4322 if (apk != null) { 4323 apk.setCompatibilityInfo(data.info); 4324 } 4325 handleConfigurationChanged(mConfiguration, data.info); 4326 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 4327 } 4328 4329 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 4330 final int N = results.size(); 4331 for (int i=0; i<N; i++) { 4332 ResultInfo ri = results.get(i); 4333 try { 4334 if (ri.mData != null) { 4335 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 4336 ri.mData.prepareToEnterProcess(); 4337 } 4338 if (DEBUG_RESULTS) Slog.v(TAG, 4339 "Delivering result to activity " + r + " : " + ri); 4340 r.activity.dispatchActivityResult(ri.mResultWho, 4341 ri.mRequestCode, ri.mResultCode, ri.mData); 4342 } catch (Exception e) { 4343 if (!mInstrumentation.onException(r.activity, e)) { 4344 throw new RuntimeException( 4345 "Failure delivering result " + ri + " to activity " 4346 + r.intent.getComponent().toShortString() 4347 + ": " + e.toString(), e); 4348 } 4349 } 4350 } 4351 } 4352 4353 @Override 4354 public void handleSendResult(IBinder token, List<ResultInfo> results) { 4355 ActivityClientRecord r = mActivities.get(token); 4356 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 4357 if (r != null) { 4358 final boolean resumed = !r.paused; 4359 if (!r.activity.mFinished && r.activity.mDecor != null 4360 && r.hideForNow && resumed) { 4361 // We had hidden the activity because it started another 4362 // one... we have gotten a result back and we are not 4363 // paused, so make sure our window is visible. 4364 updateVisibility(r, true); 4365 } 4366 if (resumed) { 4367 try { 4368 // Now we are idle. 4369 r.activity.mCalled = false; 4370 r.activity.mTemporaryPause = true; 4371 mInstrumentation.callActivityOnPause(r.activity); 4372 if (!r.activity.mCalled) { 4373 throw new SuperNotCalledException( 4374 "Activity " + r.intent.getComponent().toShortString() 4375 + " did not call through to super.onPause()"); 4376 } 4377 } catch (SuperNotCalledException e) { 4378 throw e; 4379 } catch (Exception e) { 4380 if (!mInstrumentation.onException(r.activity, e)) { 4381 throw new RuntimeException( 4382 "Unable to pause activity " 4383 + r.intent.getComponent().toShortString() 4384 + ": " + e.toString(), e); 4385 } 4386 } 4387 } 4388 checkAndBlockForNetworkAccess(); 4389 deliverResults(r, results); 4390 if (resumed) { 4391 r.activity.performResume(false, "handleSendResult"); 4392 r.activity.mTemporaryPause = false; 4393 } 4394 } 4395 } 4396 4397 /** Core implementation of activity destroy call. */ 4398 ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 4399 int configChanges, boolean getNonConfigInstance, String reason) { 4400 ActivityClientRecord r = mActivities.get(token); 4401 Class<? extends Activity> activityClass = null; 4402 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 4403 if (r != null) { 4404 activityClass = r.activity.getClass(); 4405 r.activity.mConfigChangeFlags |= configChanges; 4406 if (finishing) { 4407 r.activity.mFinished = true; 4408 } 4409 4410 performPauseActivityIfNeeded(r, "destroy"); 4411 4412 if (!r.stopped) { 4413 callActivityOnStop(r, false /* saveState */, "destroy"); 4414 } 4415 if (getNonConfigInstance) { 4416 try { 4417 r.lastNonConfigurationInstances 4418 = r.activity.retainNonConfigurationInstances(); 4419 } catch (Exception e) { 4420 if (!mInstrumentation.onException(r.activity, e)) { 4421 throw new RuntimeException( 4422 "Unable to retain activity " 4423 + r.intent.getComponent().toShortString() 4424 + ": " + e.toString(), e); 4425 } 4426 } 4427 } 4428 try { 4429 r.activity.mCalled = false; 4430 mInstrumentation.callActivityOnDestroy(r.activity); 4431 if (!r.activity.mCalled) { 4432 throw new SuperNotCalledException( 4433 "Activity " + safeToComponentShortString(r.intent) + 4434 " did not call through to super.onDestroy()"); 4435 } 4436 if (r.window != null) { 4437 r.window.closeAllPanels(); 4438 } 4439 } catch (SuperNotCalledException e) { 4440 throw e; 4441 } catch (Exception e) { 4442 if (!mInstrumentation.onException(r.activity, e)) { 4443 throw new RuntimeException( 4444 "Unable to destroy activity " + safeToComponentShortString(r.intent) 4445 + ": " + e.toString(), e); 4446 } 4447 } 4448 r.setState(ON_DESTROY); 4449 } 4450 mActivities.remove(token); 4451 mRecentDestroyedActivities.add(0, new DestroyedActivityInfo(token.hashCode(), reason)); 4452 4453 final int recentDestroyedActivitiesSize = mRecentDestroyedActivities.size(); 4454 if (recentDestroyedActivitiesSize > MAX_DESTROYED_ACTIVITIES) { 4455 mRecentDestroyedActivities.remove(recentDestroyedActivitiesSize - 1); 4456 } 4457 StrictMode.decrementExpectedActivityCount(activityClass); 4458 return r; 4459 } 4460 4461 private static String safeToComponentShortString(Intent intent) { 4462 ComponentName component = intent.getComponent(); 4463 return component == null ? "[Unknown]" : component.toShortString(); 4464 } 4465 4466 @Override 4467 public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges, 4468 boolean getNonConfigInstance, String reason) { 4469 ActivityClientRecord r = performDestroyActivity(token, finishing, 4470 configChanges, getNonConfigInstance, reason); 4471 if (r != null) { 4472 cleanUpPendingRemoveWindows(r, finishing); 4473 WindowManager wm = r.activity.getWindowManager(); 4474 View v = r.activity.mDecor; 4475 if (v != null) { 4476 if (r.activity.mVisibleFromServer) { 4477 mNumVisibleActivities--; 4478 } 4479 IBinder wtoken = v.getWindowToken(); 4480 if (r.activity.mWindowAdded) { 4481 if (r.mPreserveWindow) { 4482 // Hold off on removing this until the new activity's 4483 // window is being added. 4484 r.mPendingRemoveWindow = r.window; 4485 r.mPendingRemoveWindowManager = wm; 4486 // We can only keep the part of the view hierarchy that we control, 4487 // everything else must be removed, because it might not be able to 4488 // behave properly when activity is relaunching. 4489 r.window.clearContentView(); 4490 } else { 4491 wm.removeViewImmediate(v); 4492 } 4493 } 4494 if (wtoken != null && r.mPendingRemoveWindow == null) { 4495 WindowManagerGlobal.getInstance().closeAll(wtoken, 4496 r.activity.getClass().getName(), "Activity"); 4497 } else if (r.mPendingRemoveWindow != null) { 4498 // We're preserving only one window, others should be closed so app views 4499 // will be detached before the final tear down. It should be done now because 4500 // some components (e.g. WebView) rely on detach callbacks to perform receiver 4501 // unregister and other cleanup. 4502 WindowManagerGlobal.getInstance().closeAllExceptView(token, v, 4503 r.activity.getClass().getName(), "Activity"); 4504 } 4505 r.activity.mDecor = null; 4506 } 4507 if (r.mPendingRemoveWindow == null) { 4508 // If we are delaying the removal of the activity window, then 4509 // we can't clean up all windows here. Note that we can't do 4510 // so later either, which means any windows that aren't closed 4511 // by the app will leak. Well we try to warning them a lot 4512 // about leaking windows, because that is a bug, so if they are 4513 // using this recreate facility then they get to live with leaks. 4514 WindowManagerGlobal.getInstance().closeAll(token, 4515 r.activity.getClass().getName(), "Activity"); 4516 } 4517 4518 // Mocked out contexts won't be participating in the normal 4519 // process lifecycle, but if we're running with a proper 4520 // ApplicationContext we need to have it tear down things 4521 // cleanly. 4522 Context c = r.activity.getBaseContext(); 4523 if (c instanceof ContextImpl) { 4524 ((ContextImpl) c).scheduleFinalCleanup( 4525 r.activity.getClass().getName(), "Activity"); 4526 } 4527 } 4528 if (finishing) { 4529 try { 4530 ActivityManager.getService().activityDestroyed(token); 4531 } catch (RemoteException ex) { 4532 throw ex.rethrowFromSystemServer(); 4533 } 4534 } 4535 mSomeActivitiesChanged = true; 4536 } 4537 4538 @Override 4539 public ActivityClientRecord prepareRelaunchActivity(IBinder token, 4540 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 4541 int configChanges, MergedConfiguration config, boolean preserveWindow) { 4542 ActivityClientRecord target = null; 4543 boolean scheduleRelaunch = false; 4544 4545 synchronized (mResourcesManager) { 4546 for (int i=0; i<mRelaunchingActivities.size(); i++) { 4547 ActivityClientRecord r = mRelaunchingActivities.get(i); 4548 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r); 4549 if (r.token == token) { 4550 target = r; 4551 if (pendingResults != null) { 4552 if (r.pendingResults != null) { 4553 r.pendingResults.addAll(pendingResults); 4554 } else { 4555 r.pendingResults = pendingResults; 4556 } 4557 } 4558 if (pendingNewIntents != null) { 4559 if (r.pendingIntents != null) { 4560 r.pendingIntents.addAll(pendingNewIntents); 4561 } else { 4562 r.pendingIntents = pendingNewIntents; 4563 } 4564 } 4565 break; 4566 } 4567 } 4568 4569 if (target == null) { 4570 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null"); 4571 target = new ActivityClientRecord(); 4572 target.token = token; 4573 target.pendingResults = pendingResults; 4574 target.pendingIntents = pendingNewIntents; 4575 target.mPreserveWindow = preserveWindow; 4576 mRelaunchingActivities.add(target); 4577 scheduleRelaunch = true; 4578 } 4579 target.createdConfig = config.getGlobalConfiguration(); 4580 target.overrideConfig = config.getOverrideConfiguration(); 4581 target.pendingConfigChanges |= configChanges; 4582 } 4583 4584 return scheduleRelaunch ? target : null; 4585 } 4586 4587 @Override 4588 public void handleRelaunchActivity(ActivityClientRecord tmp, 4589 PendingTransactionActions pendingActions) { 4590 // If we are getting ready to gc after going to the background, well 4591 // we are back active so skip it. 4592 unscheduleGcIdler(); 4593 mSomeActivitiesChanged = true; 4594 4595 Configuration changedConfig = null; 4596 int configChanges = 0; 4597 4598 // First: make sure we have the most recent configuration and most 4599 // recent version of the activity, or skip it if some previous call 4600 // had taken a more recent version. 4601 synchronized (mResourcesManager) { 4602 int N = mRelaunchingActivities.size(); 4603 IBinder token = tmp.token; 4604 tmp = null; 4605 for (int i=0; i<N; i++) { 4606 ActivityClientRecord r = mRelaunchingActivities.get(i); 4607 if (r.token == token) { 4608 tmp = r; 4609 configChanges |= tmp.pendingConfigChanges; 4610 mRelaunchingActivities.remove(i); 4611 i--; 4612 N--; 4613 } 4614 } 4615 4616 if (tmp == null) { 4617 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 4618 return; 4619 } 4620 4621 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4622 + tmp.token + " with configChanges=0x" 4623 + Integer.toHexString(configChanges)); 4624 4625 if (mPendingConfiguration != null) { 4626 changedConfig = mPendingConfiguration; 4627 mPendingConfiguration = null; 4628 } 4629 } 4630 4631 if (tmp.createdConfig != null) { 4632 // If the activity manager is passing us its current config, 4633 // assume that is really what we want regardless of what we 4634 // may have pending. 4635 if (mConfiguration == null 4636 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 4637 && mConfiguration.diff(tmp.createdConfig) != 0)) { 4638 if (changedConfig == null 4639 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 4640 changedConfig = tmp.createdConfig; 4641 } 4642 } 4643 } 4644 4645 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4646 + tmp.token + ": changedConfig=" + changedConfig); 4647 4648 // If there was a pending configuration change, execute it first. 4649 if (changedConfig != null) { 4650 mCurDefaultDisplayDpi = changedConfig.densityDpi; 4651 updateDefaultDensity(); 4652 handleConfigurationChanged(changedConfig, null); 4653 } 4654 4655 ActivityClientRecord r = mActivities.get(tmp.token); 4656 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 4657 if (r == null) { 4658 return; 4659 } 4660 4661 r.activity.mConfigChangeFlags |= configChanges; 4662 r.mPreserveWindow = tmp.mPreserveWindow; 4663 4664 r.activity.mChangingConfigurations = true; 4665 4666 // If we are preserving the main window across relaunches we would also like to preserve 4667 // the children. However the client side view system does not support preserving 4668 // the child views so we notify the window manager to expect these windows to 4669 // be replaced and defer requests to destroy or hide them. This way we can achieve 4670 // visual continuity. It's important that we do this here prior to pause and destroy 4671 // as that is when we may hide or remove the child views. 4672 // 4673 // There is another scenario, if we have decided locally to relaunch the app from a 4674 // call to recreate, then none of the windows will be prepared for replacement or 4675 // preserved by the server, so we want to notify it that we are preparing to replace 4676 // everything 4677 try { 4678 if (r.mPreserveWindow) { 4679 WindowManagerGlobal.getWindowSession().prepareToReplaceWindows( 4680 r.token, true /* childrenOnly */); 4681 } 4682 } catch (RemoteException e) { 4683 throw e.rethrowFromSystemServer(); 4684 } 4685 4686 handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents, 4687 pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity"); 4688 4689 if (pendingActions != null) { 4690 // Only report a successful relaunch to WindowManager. 4691 pendingActions.setReportRelaunchToWindowManager(true); 4692 } 4693 } 4694 4695 /** Performs the activity relaunch locally vs. requesting from system-server. */ 4696 void handleRelaunchActivityLocally(IBinder token) { 4697 if (Looper.myLooper() != getLooper()) { 4698 throw new IllegalStateException("Must be called from main thread"); 4699 } 4700 4701 final ActivityClientRecord r = mActivities.get(token); 4702 if (r == null) { 4703 return; 4704 } 4705 4706 final int prevState = r.getLifecycleState(); 4707 4708 if (prevState < ON_RESUME) { 4709 Log.w(TAG, "Activity needs to be already resumed in other to be relaunched."); 4710 return; 4711 } 4712 4713 // TODO(b/73747058): Investigate converting this to use transaction to relaunch. 4714 handleRelaunchActivityInner(r, 0 /* configChanges */, null /* pendingResults */, 4715 null /* pendingIntents */, null /* pendingActions */, prevState != ON_RESUME, 4716 r.overrideConfig, "handleRelaunchActivityLocally"); 4717 4718 // Restore back to the previous state before relaunch if needed. 4719 if (prevState != r.getLifecycleState()) { 4720 mTransactionExecutor.cycleToPath(r, prevState); 4721 } 4722 } 4723 4724 private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges, 4725 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents, 4726 PendingTransactionActions pendingActions, boolean startsNotResumed, 4727 Configuration overrideConfig, String reason) { 4728 // Need to ensure state is saved. 4729 if (!r.paused) { 4730 performPauseActivity(r, false, reason, null /* pendingActions */); 4731 } 4732 if (!r.stopped) { 4733 callActivityOnStop(r, true /* saveState */, reason); 4734 } 4735 4736 handleDestroyActivity(r.token, false, configChanges, true, reason); 4737 4738 r.activity = null; 4739 r.window = null; 4740 r.hideForNow = false; 4741 r.nextIdle = null; 4742 // Merge any pending results and pending intents; don't just replace them 4743 if (pendingResults != null) { 4744 if (r.pendingResults == null) { 4745 r.pendingResults = pendingResults; 4746 } else { 4747 r.pendingResults.addAll(pendingResults); 4748 } 4749 } 4750 if (pendingIntents != null) { 4751 if (r.pendingIntents == null) { 4752 r.pendingIntents = pendingIntents; 4753 } else { 4754 r.pendingIntents.addAll(pendingIntents); 4755 } 4756 } 4757 r.startsNotResumed = startsNotResumed; 4758 r.overrideConfig = overrideConfig; 4759 4760 handleLaunchActivity(r, pendingActions); 4761 } 4762 4763 @Override 4764 public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) { 4765 try { 4766 ActivityManager.getService().activityRelaunched(token); 4767 final ActivityClientRecord r = mActivities.get(token); 4768 if (pendingActions.shouldReportRelaunchToWindowManager() && r != null 4769 && r.window != null) { 4770 r.window.reportActivityRelaunched(); 4771 } 4772 } catch (RemoteException e) { 4773 throw e.rethrowFromSystemServer(); 4774 } 4775 } 4776 4777 private void callActivityOnSaveInstanceState(ActivityClientRecord r) { 4778 r.state = new Bundle(); 4779 r.state.setAllowFds(false); 4780 if (r.isPersistable()) { 4781 r.persistentState = new PersistableBundle(); 4782 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, 4783 r.persistentState); 4784 } else { 4785 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 4786 } 4787 } 4788 4789 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 4790 boolean allActivities, Configuration newConfig) { 4791 ArrayList<ComponentCallbacks2> callbacks 4792 = new ArrayList<ComponentCallbacks2>(); 4793 4794 synchronized (mResourcesManager) { 4795 final int NAPP = mAllApplications.size(); 4796 for (int i=0; i<NAPP; i++) { 4797 callbacks.add(mAllApplications.get(i)); 4798 } 4799 final int NACT = mActivities.size(); 4800 for (int i=0; i<NACT; i++) { 4801 ActivityClientRecord ar = mActivities.valueAt(i); 4802 Activity a = ar.activity; 4803 if (a != null) { 4804 Configuration thisConfig = applyConfigCompatMainThread( 4805 mCurDefaultDisplayDpi, newConfig, 4806 ar.packageInfo.getCompatibilityInfo()); 4807 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 4808 // If the activity is currently resumed, its configuration 4809 // needs to change right now. 4810 callbacks.add(a); 4811 } else if (thisConfig != null) { 4812 // Otherwise, we will tell it about the change 4813 // the next time it is resumed or shown. Note that 4814 // the activity manager may, before then, decide the 4815 // activity needs to be destroyed to handle its new 4816 // configuration. 4817 if (DEBUG_CONFIGURATION) { 4818 Slog.v(TAG, "Setting activity " 4819 + ar.activityInfo.name + " newConfig=" + thisConfig); 4820 } 4821 ar.newConfig = thisConfig; 4822 } 4823 } 4824 } 4825 final int NSVC = mServices.size(); 4826 for (int i=0; i<NSVC; i++) { 4827 callbacks.add(mServices.valueAt(i)); 4828 } 4829 } 4830 synchronized (mProviderMap) { 4831 final int NPRV = mLocalProviders.size(); 4832 for (int i=0; i<NPRV; i++) { 4833 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 4834 } 4835 } 4836 4837 return callbacks; 4838 } 4839 4840 /** 4841 * Updates the configuration for an Activity. The ActivityClientRecord's 4842 * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for 4843 * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering 4844 * the updated Configuration. 4845 * @param r ActivityClientRecord representing the Activity. 4846 * @param newBaseConfig The new configuration to use. This may be augmented with 4847 * {@link ActivityClientRecord#overrideConfig}. 4848 */ 4849 private void performConfigurationChangedForActivity(ActivityClientRecord r, 4850 Configuration newBaseConfig) { 4851 performConfigurationChangedForActivity(r, newBaseConfig, 4852 r.activity.getDisplay().getDisplayId(), false /* movedToDifferentDisplay */); 4853 } 4854 4855 /** 4856 * Updates the configuration for an Activity. The ActivityClientRecord's 4857 * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for 4858 * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering 4859 * the updated Configuration. 4860 * @param r ActivityClientRecord representing the Activity. 4861 * @param newBaseConfig The new configuration to use. This may be augmented with 4862 * {@link ActivityClientRecord#overrideConfig}. 4863 * @param displayId The id of the display where the Activity currently resides. 4864 * @param movedToDifferentDisplay Indicates if the activity was moved to different display. 4865 * @return {@link Configuration} instance sent to client, null if not sent. 4866 */ 4867 private Configuration performConfigurationChangedForActivity(ActivityClientRecord r, 4868 Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay) { 4869 r.tmpConfig.setTo(newBaseConfig); 4870 if (r.overrideConfig != null) { 4871 r.tmpConfig.updateFrom(r.overrideConfig); 4872 } 4873 final Configuration reportedConfig = performActivityConfigurationChanged(r.activity, 4874 r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay); 4875 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 4876 return reportedConfig; 4877 } 4878 4879 /** 4880 * Creates a new Configuration only if override would modify base. Otherwise returns base. 4881 * @param base The base configuration. 4882 * @param override The update to apply to the base configuration. Can be null. 4883 * @return A Configuration representing base with override applied. 4884 */ 4885 private static Configuration createNewConfigAndUpdateIfNotNull(@NonNull Configuration base, 4886 @Nullable Configuration override) { 4887 if (override == null) { 4888 return base; 4889 } 4890 Configuration newConfig = new Configuration(base); 4891 newConfig.updateFrom(override); 4892 return newConfig; 4893 } 4894 4895 /** 4896 * Decides whether to update a component's configuration and whether to inform it. 4897 * @param cb The component callback to notify of configuration change. 4898 * @param newConfig The new configuration. 4899 */ 4900 private void performConfigurationChanged(ComponentCallbacks2 cb, Configuration newConfig) { 4901 if (!REPORT_TO_ACTIVITY) { 4902 return; 4903 } 4904 4905 // ContextThemeWrappers may override the configuration for that context. We must check and 4906 // apply any overrides defined. 4907 Configuration contextThemeWrapperOverrideConfig = null; 4908 if (cb instanceof ContextThemeWrapper) { 4909 final ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb; 4910 contextThemeWrapperOverrideConfig = contextThemeWrapper.getOverrideConfiguration(); 4911 } 4912 4913 // Apply the ContextThemeWrapper override if necessary. 4914 // NOTE: Make sure the configurations are not modified, as they are treated as immutable 4915 // in many places. 4916 final Configuration configToReport = createNewConfigAndUpdateIfNotNull( 4917 newConfig, contextThemeWrapperOverrideConfig); 4918 cb.onConfigurationChanged(configToReport); 4919 } 4920 4921 /** 4922 * Decides whether to update an Activity's configuration and whether to inform it. 4923 * @param activity The activity to notify of configuration change. 4924 * @param newConfig The new configuration. 4925 * @param amOverrideConfig The override config that differentiates the Activity's configuration 4926 * from the base global configuration. This is supplied by 4927 * ActivityManager. 4928 * @param displayId Id of the display where activity currently resides. 4929 * @param movedToDifferentDisplay Indicates if the activity was moved to different display. 4930 * @return Configuration sent to client, null if no changes and not moved to different display. 4931 */ 4932 private Configuration performActivityConfigurationChanged(Activity activity, 4933 Configuration newConfig, Configuration amOverrideConfig, int displayId, 4934 boolean movedToDifferentDisplay) { 4935 if (activity == null) { 4936 throw new IllegalArgumentException("No activity provided."); 4937 } 4938 final IBinder activityToken = activity.getActivityToken(); 4939 if (activityToken == null) { 4940 throw new IllegalArgumentException("Activity token not set. Is the activity attached?"); 4941 } 4942 4943 boolean shouldChangeConfig = false; 4944 if (activity.mCurrentConfig == null) { 4945 shouldChangeConfig = true; 4946 } else { 4947 // If the new config is the same as the config this Activity is already running with and 4948 // the override config also didn't change, then don't bother calling 4949 // onConfigurationChanged. 4950 final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig); 4951 4952 if (diff != 0 || !mResourcesManager.isSameResourcesOverrideConfig(activityToken, 4953 amOverrideConfig)) { 4954 // Always send the task-level config changes. For system-level configuration, if 4955 // this activity doesn't handle any of the config changes, then don't bother 4956 // calling onConfigurationChanged as we're going to destroy it. 4957 if (!mUpdatingSystemConfig 4958 || (~activity.mActivityInfo.getRealConfigChanged() & diff) == 0 4959 || !REPORT_TO_ACTIVITY) { 4960 shouldChangeConfig = true; 4961 } 4962 } 4963 } 4964 if (!shouldChangeConfig && !movedToDifferentDisplay) { 4965 // Nothing significant, don't proceed with updating and reporting. 4966 return null; 4967 } 4968 4969 // Propagate the configuration change to ResourcesManager and Activity. 4970 4971 // ContextThemeWrappers may override the configuration for that context. We must check and 4972 // apply any overrides defined. 4973 Configuration contextThemeWrapperOverrideConfig = activity.getOverrideConfiguration(); 4974 4975 // We only update an Activity's configuration if this is not a global configuration change. 4976 // This must also be done before the callback, or else we violate the contract that the new 4977 // resources are available in ComponentCallbacks2#onConfigurationChanged(Configuration). 4978 // Also apply the ContextThemeWrapper override if necessary. 4979 // NOTE: Make sure the configurations are not modified, as they are treated as immutable in 4980 // many places. 4981 final Configuration finalOverrideConfig = createNewConfigAndUpdateIfNotNull( 4982 amOverrideConfig, contextThemeWrapperOverrideConfig); 4983 mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig, 4984 displayId, movedToDifferentDisplay); 4985 4986 activity.mConfigChangeFlags = 0; 4987 activity.mCurrentConfig = new Configuration(newConfig); 4988 4989 // Apply the ContextThemeWrapper override if necessary. 4990 // NOTE: Make sure the configurations are not modified, as they are treated as immutable 4991 // in many places. 4992 final Configuration configToReport = createNewConfigAndUpdateIfNotNull(newConfig, 4993 contextThemeWrapperOverrideConfig); 4994 4995 if (!REPORT_TO_ACTIVITY) { 4996 // Not configured to report to activity. 4997 return configToReport; 4998 } 4999 5000 if (movedToDifferentDisplay) { 5001 activity.dispatchMovedToDisplay(displayId, configToReport); 5002 } 5003 5004 if (shouldChangeConfig) { 5005 activity.mCalled = false; 5006 activity.onConfigurationChanged(configToReport); 5007 if (!activity.mCalled) { 5008 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() + 5009 " did not call through to super.onConfigurationChanged()"); 5010 } 5011 } 5012 5013 return configToReport; 5014 } 5015 5016 public final void applyConfigurationToResources(Configuration config) { 5017 synchronized (mResourcesManager) { 5018 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 5019 } 5020 } 5021 5022 final Configuration applyCompatConfiguration(int displayDensity) { 5023 Configuration config = mConfiguration; 5024 if (mCompatConfiguration == null) { 5025 mCompatConfiguration = new Configuration(); 5026 } 5027 mCompatConfiguration.setTo(mConfiguration); 5028 if (mResourcesManager.applyCompatConfigurationLocked(displayDensity, 5029 mCompatConfiguration)) { 5030 config = mCompatConfiguration; 5031 } 5032 return config; 5033 } 5034 5035 @Override 5036 public void handleConfigurationChanged(Configuration config) { 5037 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged"); 5038 mCurDefaultDisplayDpi = config.densityDpi; 5039 mUpdatingSystemConfig = true; 5040 try { 5041 handleConfigurationChanged(config, null /* compat */); 5042 } finally { 5043 mUpdatingSystemConfig = false; 5044 } 5045 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5046 } 5047 5048 private void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 5049 5050 int configDiff = 0; 5051 5052 // This flag tracks whether the new configuration is fundamentally equivalent to the 5053 // existing configuration. This is necessary to determine whether non-activity 5054 // callbacks should receive notice when the only changes are related to non-public fields. 5055 // We do not gate calling {@link #performActivityConfigurationChanged} based on this flag 5056 // as that method uses the same check on the activity config override as well. 5057 final boolean equivalent = config != null && mConfiguration != null 5058 && (0 == mConfiguration.diffPublicOnly(config)); 5059 final Theme systemTheme = getSystemContext().getTheme(); 5060 final Theme systemUiTheme = getSystemUiContext().getTheme(); 5061 5062 synchronized (mResourcesManager) { 5063 if (mPendingConfiguration != null) { 5064 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 5065 config = mPendingConfiguration; 5066 mCurDefaultDisplayDpi = config.densityDpi; 5067 updateDefaultDensity(); 5068 } 5069 mPendingConfiguration = null; 5070 } 5071 5072 if (config == null) { 5073 return; 5074 } 5075 5076 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 5077 + config); 5078 5079 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 5080 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), 5081 mResourcesManager.getConfiguration().getLocales()); 5082 5083 if (mConfiguration == null) { 5084 mConfiguration = new Configuration(); 5085 } 5086 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 5087 return; 5088 } 5089 5090 configDiff = mConfiguration.updateFrom(config); 5091 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 5092 5093 if ((systemTheme.getChangingConfigurations() & configDiff) != 0) { 5094 systemTheme.rebase(); 5095 } 5096 5097 if ((systemUiTheme.getChangingConfigurations() & configDiff) != 0) { 5098 systemUiTheme.rebase(); 5099 } 5100 } 5101 5102 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 5103 5104 freeTextLayoutCachesIfNeeded(configDiff); 5105 5106 if (callbacks != null) { 5107 final int N = callbacks.size(); 5108 for (int i=0; i<N; i++) { 5109 ComponentCallbacks2 cb = callbacks.get(i); 5110 if (cb instanceof Activity) { 5111 // If callback is an Activity - call corresponding method to consider override 5112 // config and avoid onConfigurationChanged if it hasn't changed. 5113 Activity a = (Activity) cb; 5114 performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()), 5115 config); 5116 } else if (!equivalent) { 5117 performConfigurationChanged(cb, config); 5118 } 5119 } 5120 } 5121 } 5122 5123 void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) { 5124 // Updates triggered by package installation go through a package update 5125 // receiver. Here we try to capture ApplicationInfo changes that are 5126 // caused by other sources, such as overlays. That means we want to be as conservative 5127 // about code changes as possible. Take the diff of the old ApplicationInfo and the new 5128 // to see if anything needs to change. 5129 LoadedApk apk; 5130 LoadedApk resApk; 5131 // Update all affected loaded packages with new package information 5132 synchronized (mResourcesManager) { 5133 WeakReference<LoadedApk> ref = mPackages.get(ai.packageName); 5134 apk = ref != null ? ref.get() : null; 5135 ref = mResourcePackages.get(ai.packageName); 5136 resApk = ref != null ? ref.get() : null; 5137 } 5138 if (apk != null) { 5139 final ArrayList<String> oldPaths = new ArrayList<>(); 5140 LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths); 5141 apk.updateApplicationInfo(ai, oldPaths); 5142 } 5143 if (resApk != null) { 5144 final ArrayList<String> oldPaths = new ArrayList<>(); 5145 LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths); 5146 resApk.updateApplicationInfo(ai, oldPaths); 5147 } 5148 synchronized (mResourcesManager) { 5149 // Update all affected Resources objects to use new ResourcesImpl 5150 mResourcesManager.applyNewResourceDirsLocked(ai.sourceDir, ai.resourceDirs); 5151 } 5152 5153 ApplicationPackageManager.configurationChanged(); 5154 5155 // Trigger a regular Configuration change event, only with a different assetsSeq number 5156 // so that we actually call through to all components. 5157 // TODO(adamlesinski): Change this to make use of ActivityManager's upcoming ability to 5158 // store configurations per-process. 5159 Configuration newConfig = new Configuration(); 5160 newConfig.assetsSeq = (mConfiguration != null ? mConfiguration.assetsSeq : 0) + 1; 5161 handleConfigurationChanged(newConfig, null); 5162 5163 relaunchAllActivities(); 5164 } 5165 5166 static void freeTextLayoutCachesIfNeeded(int configDiff) { 5167 if (configDiff != 0) { 5168 // Ask text layout engine to free its caches if there is a locale change 5169 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 5170 if (hasLocaleConfigChange) { 5171 Canvas.freeTextLayoutCaches(); 5172 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 5173 } 5174 } 5175 } 5176 5177 /** 5178 * Handle new activity configuration and/or move to a different display. 5179 * @param activityToken Target activity token. 5180 * @param overrideConfig Activity override config. 5181 * @param displayId Id of the display where activity was moved to, -1 if there was no move and 5182 * value didn't change. 5183 */ 5184 @Override 5185 public void handleActivityConfigurationChanged(IBinder activityToken, 5186 Configuration overrideConfig, int displayId) { 5187 ActivityClientRecord r = mActivities.get(activityToken); 5188 // Check input params. 5189 if (r == null || r.activity == null) { 5190 if (DEBUG_CONFIGURATION) Slog.w(TAG, "Not found target activity to report to: " + r); 5191 return; 5192 } 5193 final boolean movedToDifferentDisplay = displayId != INVALID_DISPLAY 5194 && displayId != r.activity.getDisplay().getDisplayId(); 5195 5196 // Perform updates. 5197 r.overrideConfig = overrideConfig; 5198 final ViewRootImpl viewRoot = r.activity.mDecor != null 5199 ? r.activity.mDecor.getViewRootImpl() : null; 5200 5201 if (movedToDifferentDisplay) { 5202 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity moved to display, activity:" 5203 + r.activityInfo.name + ", displayId=" + displayId 5204 + ", config=" + overrideConfig); 5205 5206 final Configuration reportedConfig = performConfigurationChangedForActivity(r, 5207 mCompatConfiguration, displayId, true /* movedToDifferentDisplay */); 5208 if (viewRoot != null) { 5209 viewRoot.onMovedToDisplay(displayId, reportedConfig); 5210 } 5211 } else { 5212 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 5213 + r.activityInfo.name + ", config=" + overrideConfig); 5214 performConfigurationChangedForActivity(r, mCompatConfiguration); 5215 } 5216 // Notify the ViewRootImpl instance about configuration changes. It may have initiated this 5217 // update to make sure that resources are updated before updating itself. 5218 if (viewRoot != null) { 5219 viewRoot.updateConfiguration(displayId); 5220 } 5221 mSomeActivitiesChanged = true; 5222 } 5223 5224 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 5225 if (start) { 5226 try { 5227 switch (profileType) { 5228 default: 5229 mProfiler.setProfiler(profilerInfo); 5230 mProfiler.startProfiling(); 5231 break; 5232 } 5233 } catch (RuntimeException e) { 5234 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile 5235 + " -- can the process access this path?"); 5236 } finally { 5237 profilerInfo.closeFd(); 5238 } 5239 } else { 5240 switch (profileType) { 5241 default: 5242 mProfiler.stopProfiling(); 5243 break; 5244 } 5245 } 5246 } 5247 5248 /** 5249 * Public entrypoint to stop profiling. This is required to end profiling when the app crashes, 5250 * so that profiler data won't be lost. 5251 * 5252 * @hide 5253 */ 5254 public void stopProfiling() { 5255 if (mProfiler != null) { 5256 mProfiler.stopProfiling(); 5257 } 5258 } 5259 5260 static void handleDumpHeap(DumpHeapData dhd) { 5261 if (dhd.runGc) { 5262 System.gc(); 5263 System.runFinalization(); 5264 System.gc(); 5265 } 5266 if (dhd.managed) { 5267 try { 5268 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 5269 } catch (IOException e) { 5270 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 5271 + " -- can the process access this path?"); 5272 } finally { 5273 try { 5274 dhd.fd.close(); 5275 } catch (IOException e) { 5276 Slog.w(TAG, "Failure closing profile fd", e); 5277 } 5278 } 5279 } else if (dhd.mallocInfo) { 5280 Debug.dumpNativeMallocInfo(dhd.fd.getFileDescriptor()); 5281 } else { 5282 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 5283 } 5284 try { 5285 ActivityManager.getService().dumpHeapFinished(dhd.path); 5286 } catch (RemoteException e) { 5287 throw e.rethrowFromSystemServer(); 5288 } 5289 } 5290 5291 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 5292 boolean hasPkgInfo = false; 5293 switch (cmd) { 5294 case ApplicationThreadConstants.PACKAGE_REMOVED: 5295 case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL: 5296 { 5297 final boolean killApp = cmd == ApplicationThreadConstants.PACKAGE_REMOVED; 5298 if (packages == null) { 5299 break; 5300 } 5301 synchronized (mResourcesManager) { 5302 for (int i = packages.length - 1; i >= 0; i--) { 5303 if (!hasPkgInfo) { 5304 WeakReference<LoadedApk> ref = mPackages.get(packages[i]); 5305 if (ref != null && ref.get() != null) { 5306 hasPkgInfo = true; 5307 } else { 5308 ref = mResourcePackages.get(packages[i]); 5309 if (ref != null && ref.get() != null) { 5310 hasPkgInfo = true; 5311 } 5312 } 5313 } 5314 if (killApp) { 5315 mPackages.remove(packages[i]); 5316 mResourcePackages.remove(packages[i]); 5317 } 5318 } 5319 } 5320 break; 5321 } 5322 case ApplicationThreadConstants.PACKAGE_REPLACED: 5323 { 5324 if (packages == null) { 5325 break; 5326 } 5327 synchronized (mResourcesManager) { 5328 for (int i = packages.length - 1; i >= 0; i--) { 5329 WeakReference<LoadedApk> ref = mPackages.get(packages[i]); 5330 LoadedApk pkgInfo = ref != null ? ref.get() : null; 5331 if (pkgInfo != null) { 5332 hasPkgInfo = true; 5333 } else { 5334 ref = mResourcePackages.get(packages[i]); 5335 pkgInfo = ref != null ? ref.get() : null; 5336 if (pkgInfo != null) { 5337 hasPkgInfo = true; 5338 } 5339 } 5340 // If the package is being replaced, yet it still has a valid 5341 // LoadedApk object, the package was updated with _DONT_KILL. 5342 // Adjust it's internal references to the application info and 5343 // resources. 5344 if (pkgInfo != null) { 5345 try { 5346 final String packageName = packages[i]; 5347 final ApplicationInfo aInfo = 5348 sPackageManager.getApplicationInfo( 5349 packageName, 5350 PackageManager.GET_SHARED_LIBRARY_FILES, 5351 UserHandle.myUserId()); 5352 5353 if (mActivities.size() > 0) { 5354 for (ActivityClientRecord ar : mActivities.values()) { 5355 if (ar.activityInfo.applicationInfo.packageName 5356 .equals(packageName)) { 5357 ar.activityInfo.applicationInfo = aInfo; 5358 ar.packageInfo = pkgInfo; 5359 } 5360 } 5361 } 5362 final List<String> oldPaths = 5363 sPackageManager.getPreviousCodePaths(packageName); 5364 pkgInfo.updateApplicationInfo(aInfo, oldPaths); 5365 } catch (RemoteException e) { 5366 } 5367 } 5368 } 5369 } 5370 break; 5371 } 5372 } 5373 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo); 5374 } 5375 5376 final void handleLowMemory() { 5377 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 5378 5379 final int N = callbacks.size(); 5380 for (int i=0; i<N; i++) { 5381 callbacks.get(i).onLowMemory(); 5382 } 5383 5384 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 5385 if (Process.myUid() != Process.SYSTEM_UID) { 5386 int sqliteReleased = SQLiteDatabase.releaseMemory(); 5387 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 5388 } 5389 5390 // Ask graphics to free up as much as possible (font/image caches) 5391 Canvas.freeCaches(); 5392 5393 // Ask text layout engine to free also as much as possible 5394 Canvas.freeTextLayoutCaches(); 5395 5396 BinderInternal.forceGc("mem"); 5397 } 5398 5399 final void handleTrimMemory(int level) { 5400 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 5401 5402 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 5403 5404 final int N = callbacks.size(); 5405 for (int i = 0; i < N; i++) { 5406 callbacks.get(i).onTrimMemory(level); 5407 } 5408 5409 WindowManagerGlobal.getInstance().trimMemory(level); 5410 } 5411 5412 private void setupGraphicsSupport(Context context) { 5413 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport"); 5414 5415 // The system package doesn't have real data directories, so don't set up cache paths. 5416 if (!"android".equals(context.getPackageName())) { 5417 // This cache location probably points at credential-encrypted 5418 // storage which may not be accessible yet; assign it anyway instead 5419 // of pointing at device-encrypted storage. 5420 final File cacheDir = context.getCacheDir(); 5421 if (cacheDir != null) { 5422 // Provide a usable directory for temporary files 5423 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 5424 } else { 5425 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property " 5426 + "due to missing cache directory"); 5427 } 5428 5429 // Setup a location to store generated/compiled graphics code. 5430 final Context deviceContext = context.createDeviceProtectedStorageContext(); 5431 final File codeCacheDir = deviceContext.getCodeCacheDir(); 5432 if (codeCacheDir != null) { 5433 try { 5434 int uid = Process.myUid(); 5435 String[] packages = getPackageManager().getPackagesForUid(uid); 5436 if (packages != null) { 5437 ThreadedRenderer.setupDiskCache(codeCacheDir); 5438 RenderScriptCacheDir.setupDiskCache(codeCacheDir); 5439 } 5440 } catch (RemoteException e) { 5441 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5442 throw e.rethrowFromSystemServer(); 5443 } 5444 } else { 5445 Log.w(TAG, "Unable to use shader/script cache: missing code-cache directory"); 5446 } 5447 } 5448 5449 GraphicsEnvironment.getInstance().setup(context); 5450 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5451 } 5452 5453 private void updateDefaultDensity() { 5454 final int densityDpi = mCurDefaultDisplayDpi; 5455 if (!mDensityCompatMode 5456 && densityDpi != Configuration.DENSITY_DPI_UNDEFINED 5457 && densityDpi != DisplayMetrics.DENSITY_DEVICE) { 5458 DisplayMetrics.DENSITY_DEVICE = densityDpi; 5459 Bitmap.setDefaultDensity(densityDpi); 5460 } 5461 } 5462 5463 /** 5464 * Returns the correct library directory for the current ABI. 5465 * <p> 5466 * If we're dealing with a multi-arch application that has both 32 and 64 bit shared 5467 * libraries, we might need to choose the secondary depending on what the current 5468 * runtime's instruction set is. 5469 */ 5470 private String getInstrumentationLibrary(ApplicationInfo appInfo, InstrumentationInfo insInfo) { 5471 if (appInfo.primaryCpuAbi != null && appInfo.secondaryCpuAbi != null) { 5472 // Get the instruction set supported by the secondary ABI. In the presence 5473 // of a native bridge this might be different than the one secondary ABI used. 5474 String secondaryIsa = 5475 VMRuntime.getInstructionSet(appInfo.secondaryCpuAbi); 5476 final String secondaryDexCodeIsa = 5477 SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa); 5478 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa; 5479 5480 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet(); 5481 if (runtimeIsa.equals(secondaryIsa)) { 5482 return insInfo.secondaryNativeLibraryDir; 5483 } 5484 } 5485 return insInfo.nativeLibraryDir; 5486 } 5487 5488 /** 5489 * The LocaleList set for the app's resources may have been shuffled so that the preferred 5490 * Locale is at position 0. We must find the index of this preferred Locale in the 5491 * original LocaleList. 5492 */ 5493 private void updateLocaleListFromAppContext(Context context, LocaleList newLocaleList) { 5494 final Locale bestLocale = context.getResources().getConfiguration().getLocales().get(0); 5495 final int newLocaleListSize = newLocaleList.size(); 5496 for (int i = 0; i < newLocaleListSize; i++) { 5497 if (bestLocale.equals(newLocaleList.get(i))) { 5498 LocaleList.setDefault(newLocaleList, i); 5499 return; 5500 } 5501 } 5502 5503 // The app may have overridden the LocaleList with its own Locale 5504 // (not present in the available list). Push the chosen Locale 5505 // to the front of the list. 5506 LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList)); 5507 } 5508 5509 private void handleBindApplication(AppBindData data) { 5510 // Register the UI Thread as a sensitive thread to the runtime. 5511 VMRuntime.registerSensitiveThread(); 5512 if (data.trackAllocation) { 5513 DdmVmInternal.enableRecentAllocations(true); 5514 } 5515 5516 // Note when this process has started. 5517 Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); 5518 5519 mBoundApplication = data; 5520 mConfiguration = new Configuration(data.config); 5521 mCompatConfiguration = new Configuration(data.config); 5522 5523 mProfiler = new Profiler(); 5524 String agent = null; 5525 if (data.initProfilerInfo != null) { 5526 mProfiler.profileFile = data.initProfilerInfo.profileFile; 5527 mProfiler.profileFd = data.initProfilerInfo.profileFd; 5528 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; 5529 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; 5530 mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput; 5531 if (data.initProfilerInfo.attachAgentDuringBind) { 5532 agent = data.initProfilerInfo.agent; 5533 } 5534 } 5535 5536 // send up app name; do this *before* waiting for debugger 5537 Process.setArgV0(data.processName); 5538 android.ddm.DdmHandleAppName.setAppName(data.processName, 5539 UserHandle.myUserId()); 5540 5541 if (mProfiler.profileFd != null) { 5542 mProfiler.startProfiling(); 5543 } 5544 5545 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 5546 // implementation to use the pool executor. Normally, we use the 5547 // serialized executor as the default. This has to happen in the 5548 // main thread so the main looper is set right. 5549 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 5550 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 5551 } 5552 5553 Message.updateCheckRecycle(data.appInfo.targetSdkVersion); 5554 5555 // Prior to P, internal calls to decode Bitmaps used BitmapFactory, 5556 // which may scale up to account for density. In P, we switched to 5557 // ImageDecoder, which skips the upscale to save memory. ImageDecoder 5558 // needs to still scale up in older apps, in case they rely on the 5559 // size of the Bitmap without considering its density. 5560 ImageDecoder.sApiLevel = data.appInfo.targetSdkVersion; 5561 5562 /* 5563 * Before spawning a new process, reset the time zone to be the system time zone. 5564 * This needs to be done because the system time zone could have changed after the 5565 * the spawning of this process. Without doing this this process would have the incorrect 5566 * system time zone. 5567 */ 5568 TimeZone.setDefault(null); 5569 5570 /* 5571 * Set the LocaleList. This may change once we create the App Context. 5572 */ 5573 LocaleList.setDefault(data.config.getLocales()); 5574 5575 synchronized (mResourcesManager) { 5576 /* 5577 * Update the system configuration since its preloaded and might not 5578 * reflect configuration changes. The configuration object passed 5579 * in AppBindData can be safely assumed to be up to date 5580 */ 5581 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 5582 mCurDefaultDisplayDpi = data.config.densityDpi; 5583 5584 // This calls mResourcesManager so keep it within the synchronized block. 5585 applyCompatConfiguration(mCurDefaultDisplayDpi); 5586 } 5587 5588 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 5589 5590 if (agent != null) { 5591 handleAttachAgent(agent, data.info); 5592 } 5593 5594 /** 5595 * Switch this process to density compatibility mode if needed. 5596 */ 5597 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 5598 == 0) { 5599 mDensityCompatMode = true; 5600 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 5601 } 5602 updateDefaultDensity(); 5603 5604 final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24); 5605 Boolean is24Hr = null; 5606 if (use24HourSetting != null) { 5607 is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE; 5608 } 5609 // null : use locale default for 12/24 hour formatting, 5610 // false : use 12 hour format, 5611 // true : use 24 hour format. 5612 DateFormat.set24HourTimePref(is24Hr); 5613 5614 View.mDebugViewAttributes = 5615 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 5616 5617 StrictMode.initThreadDefaults(data.appInfo); 5618 StrictMode.initVmDefaults(data.appInfo); 5619 5620 // We deprecated Build.SERIAL and only apps that target pre NMR1 5621 // SDK can see it. Since access to the serial is now behind a 5622 // permission we push down the value and here we fix it up 5623 // before any app code has been loaded. 5624 try { 5625 Field field = Build.class.getDeclaredField("SERIAL"); 5626 field.setAccessible(true); 5627 field.set(Build.class, data.buildSerial); 5628 } catch (NoSuchFieldException | IllegalAccessException e) { 5629 /* ignore */ 5630 } 5631 5632 if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) { 5633 // XXX should have option to change the port. 5634 Debug.changeDebugPort(8100); 5635 if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) { 5636 Slog.w(TAG, "Application " + data.info.getPackageName() 5637 + " is waiting for the debugger on port 8100..."); 5638 5639 IActivityManager mgr = ActivityManager.getService(); 5640 try { 5641 mgr.showWaitingForDebugger(mAppThread, true); 5642 } catch (RemoteException ex) { 5643 throw ex.rethrowFromSystemServer(); 5644 } 5645 5646 Debug.waitForDebugger(); 5647 5648 try { 5649 mgr.showWaitingForDebugger(mAppThread, false); 5650 } catch (RemoteException ex) { 5651 throw ex.rethrowFromSystemServer(); 5652 } 5653 5654 } else { 5655 Slog.w(TAG, "Application " + data.info.getPackageName() 5656 + " can be debugged on port 8100..."); 5657 } 5658 } 5659 5660 // Allow application-generated systrace messages if we're debuggable. 5661 boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 5662 Trace.setAppTracingAllowed(isAppDebuggable); 5663 if (isAppDebuggable && data.enableBinderTracking) { 5664 Binder.enableTracing(); 5665 } 5666 5667 /** 5668 * Initialize the default http proxy in this process for the reasons we set the time zone. 5669 */ 5670 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies"); 5671 final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 5672 if (b != null) { 5673 // In pre-boot mode (doing initial launch to collect password), not 5674 // all system is up. This includes the connectivity service, so don't 5675 // crash if we can't get it. 5676 final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 5677 try { 5678 final ProxyInfo proxyInfo = service.getProxyForNetwork(null); 5679 Proxy.setHttpProxySystemProperty(proxyInfo); 5680 } catch (RemoteException e) { 5681 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5682 throw e.rethrowFromSystemServer(); 5683 } 5684 } 5685 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5686 5687 // Instrumentation info affects the class loader, so load it before 5688 // setting up the app context. 5689 final InstrumentationInfo ii; 5690 if (data.instrumentationName != null) { 5691 try { 5692 ii = new ApplicationPackageManager(null, getPackageManager()) 5693 .getInstrumentationInfo(data.instrumentationName, 0); 5694 } catch (PackageManager.NameNotFoundException e) { 5695 throw new RuntimeException( 5696 "Unable to find instrumentation info for: " + data.instrumentationName); 5697 } 5698 5699 mInstrumentationPackageName = ii.packageName; 5700 mInstrumentationAppDir = ii.sourceDir; 5701 mInstrumentationSplitAppDirs = ii.splitSourceDirs; 5702 mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); 5703 mInstrumentedAppDir = data.info.getAppDir(); 5704 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); 5705 mInstrumentedLibDir = data.info.getLibDir(); 5706 } else { 5707 ii = null; 5708 } 5709 5710 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 5711 updateLocaleListFromAppContext(appContext, 5712 mResourcesManager.getConfiguration().getLocales()); 5713 5714 if (!Process.isIsolated()) { 5715 final int oldMask = StrictMode.allowThreadDiskWritesMask(); 5716 try { 5717 setupGraphicsSupport(appContext); 5718 } finally { 5719 StrictMode.setThreadPolicyMask(oldMask); 5720 } 5721 } 5722 5723 // If we use profiles, setup the dex reporter to notify package manager 5724 // of any relevant dex loads. The idle maintenance job will use the information 5725 // reported to optimize the loaded dex files. 5726 // Note that we only need one global reporter per app. 5727 // Make sure we do this before calling onCreate so that we can capture the 5728 // complete application startup. 5729 if (SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) { 5730 BaseDexClassLoader.setReporter(DexLoadReporter.getInstance()); 5731 } 5732 5733 // Install the Network Security Config Provider. This must happen before the application 5734 // code is loaded to prevent issues with instances of TLS objects being created before 5735 // the provider is installed. 5736 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "NetworkSecurityConfigProvider.install"); 5737 NetworkSecurityConfigProvider.install(appContext); 5738 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5739 5740 // Continue loading instrumentation. 5741 if (ii != null) { 5742 ApplicationInfo instrApp; 5743 try { 5744 instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0, 5745 UserHandle.myUserId()); 5746 } catch (RemoteException e) { 5747 instrApp = null; 5748 } 5749 if (instrApp == null) { 5750 instrApp = new ApplicationInfo(); 5751 } 5752 ii.copyTo(instrApp); 5753 instrApp.initForUser(UserHandle.myUserId()); 5754 final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 5755 appContext.getClassLoader(), false, true, false); 5756 final ContextImpl instrContext = ContextImpl.createAppContext(this, pi); 5757 5758 try { 5759 final ClassLoader cl = instrContext.getClassLoader(); 5760 mInstrumentation = (Instrumentation) 5761 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 5762 } catch (Exception e) { 5763 throw new RuntimeException( 5764 "Unable to instantiate instrumentation " 5765 + data.instrumentationName + ": " + e.toString(), e); 5766 } 5767 5768 final ComponentName component = new ComponentName(ii.packageName, ii.name); 5769 mInstrumentation.init(this, instrContext, appContext, component, 5770 data.instrumentationWatcher, data.instrumentationUiAutomationConnection); 5771 5772 if (mProfiler.profileFile != null && !ii.handleProfiling 5773 && mProfiler.profileFd == null) { 5774 mProfiler.handlingProfiling = true; 5775 final File file = new File(mProfiler.profileFile); 5776 file.getParentFile().mkdirs(); 5777 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 5778 } 5779 } else { 5780 mInstrumentation = new Instrumentation(); 5781 mInstrumentation.basicInit(this); 5782 } 5783 5784 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 5785 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 5786 } else { 5787 // Small heap, clamp to the current growth limit and let the heap release 5788 // pages after the growth limit to the non growth limit capacity. b/18387825 5789 dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); 5790 } 5791 5792 // Allow disk access during application and provider setup. This could 5793 // block processing ordered broadcasts, but later processing would 5794 // probably end up doing the same disk access. 5795 Application app; 5796 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 5797 final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy(); 5798 try { 5799 // If the app is being launched for full backup or restore, bring it up in 5800 // a restricted environment with the base application class. 5801 app = data.info.makeApplication(data.restrictedBackupMode, null); 5802 5803 // Propagate autofill compat state 5804 app.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled); 5805 5806 mInitialApplication = app; 5807 5808 // don't bring up providers in restricted mode; they may depend on the 5809 // app's custom Application class 5810 if (!data.restrictedBackupMode) { 5811 if (!ArrayUtils.isEmpty(data.providers)) { 5812 installContentProviders(app, data.providers); 5813 // For process that contains content providers, we want to 5814 // ensure that the JIT is enabled "at some point". 5815 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 5816 } 5817 } 5818 5819 // Do this after providers, since instrumentation tests generally start their 5820 // test thread at this point, and we don't want that racing. 5821 try { 5822 mInstrumentation.onCreate(data.instrumentationArgs); 5823 } 5824 catch (Exception e) { 5825 throw new RuntimeException( 5826 "Exception thrown in onCreate() of " 5827 + data.instrumentationName + ": " + e.toString(), e); 5828 } 5829 try { 5830 mInstrumentation.callApplicationOnCreate(app); 5831 } catch (Exception e) { 5832 if (!mInstrumentation.onException(app, e)) { 5833 throw new RuntimeException( 5834 "Unable to create application " + app.getClass().getName() 5835 + ": " + e.toString(), e); 5836 } 5837 } 5838 } finally { 5839 // If the app targets < O-MR1, or doesn't change the thread policy 5840 // during startup, clobber the policy to maintain behavior of b/36951662 5841 if (data.appInfo.targetSdkVersion <= Build.VERSION_CODES.O 5842 || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) { 5843 StrictMode.setThreadPolicy(savedPolicy); 5844 } 5845 } 5846 5847 // Preload fonts resources 5848 FontsContract.setApplicationContextForResources(appContext); 5849 if (!Process.isIsolated()) { 5850 try { 5851 final ApplicationInfo info = 5852 getPackageManager().getApplicationInfo( 5853 data.appInfo.packageName, 5854 PackageManager.GET_META_DATA /*flags*/, 5855 UserHandle.myUserId()); 5856 if (info.metaData != null) { 5857 final int preloadedFontsResource = info.metaData.getInt( 5858 ApplicationInfo.METADATA_PRELOADED_FONTS, 0); 5859 if (preloadedFontsResource != 0) { 5860 data.info.getResources().preloadFonts(preloadedFontsResource); 5861 } 5862 } 5863 } catch (RemoteException e) { 5864 throw e.rethrowFromSystemServer(); 5865 } 5866 } 5867 } 5868 5869 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 5870 IActivityManager am = ActivityManager.getService(); 5871 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 5872 && mProfiler.profileFd == null) { 5873 Debug.stopMethodTracing(); 5874 } 5875 //Slog.i(TAG, "am: " + ActivityManager.getService() 5876 // + ", app thr: " + mAppThread); 5877 try { 5878 am.finishInstrumentation(mAppThread, resultCode, results); 5879 } catch (RemoteException ex) { 5880 throw ex.rethrowFromSystemServer(); 5881 } 5882 } 5883 5884 private void installContentProviders( 5885 Context context, List<ProviderInfo> providers) { 5886 final ArrayList<ContentProviderHolder> results = new ArrayList<>(); 5887 5888 for (ProviderInfo cpi : providers) { 5889 if (DEBUG_PROVIDER) { 5890 StringBuilder buf = new StringBuilder(128); 5891 buf.append("Pub "); 5892 buf.append(cpi.authority); 5893 buf.append(": "); 5894 buf.append(cpi.name); 5895 Log.i(TAG, buf.toString()); 5896 } 5897 ContentProviderHolder cph = installProvider(context, null, cpi, 5898 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 5899 if (cph != null) { 5900 cph.noReleaseNeeded = true; 5901 results.add(cph); 5902 } 5903 } 5904 5905 try { 5906 ActivityManager.getService().publishContentProviders( 5907 getApplicationThread(), results); 5908 } catch (RemoteException ex) { 5909 throw ex.rethrowFromSystemServer(); 5910 } 5911 } 5912 5913 public final IContentProvider acquireProvider( 5914 Context c, String auth, int userId, boolean stable) { 5915 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 5916 if (provider != null) { 5917 return provider; 5918 } 5919 5920 // There is a possible race here. Another thread may try to acquire 5921 // the same provider at the same time. When this happens, we want to ensure 5922 // that the first one wins. 5923 // Note that we cannot hold the lock while acquiring and installing the 5924 // provider since it might take a long time to run and it could also potentially 5925 // be re-entrant in the case where the provider is in the same process. 5926 ContentProviderHolder holder = null; 5927 try { 5928 holder = ActivityManager.getService().getContentProvider( 5929 getApplicationThread(), auth, userId, stable); 5930 } catch (RemoteException ex) { 5931 throw ex.rethrowFromSystemServer(); 5932 } 5933 if (holder == null) { 5934 Slog.e(TAG, "Failed to find provider info for " + auth); 5935 return null; 5936 } 5937 5938 // Install provider will increment the reference count for us, and break 5939 // any ties in the race. 5940 holder = installProvider(c, holder, holder.info, 5941 true /*noisy*/, holder.noReleaseNeeded, stable); 5942 return holder.provider; 5943 } 5944 5945 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 5946 if (stable) { 5947 prc.stableCount += 1; 5948 if (prc.stableCount == 1) { 5949 // We are acquiring a new stable reference on the provider. 5950 int unstableDelta; 5951 if (prc.removePending) { 5952 // We have a pending remove operation, which is holding the 5953 // last unstable reference. At this point we are converting 5954 // that unstable reference to our new stable reference. 5955 unstableDelta = -1; 5956 // Cancel the removal of the provider. 5957 if (DEBUG_PROVIDER) { 5958 Slog.v(TAG, "incProviderRef: stable " 5959 + "snatched provider from the jaws of death"); 5960 } 5961 prc.removePending = false; 5962 // There is a race! It fails to remove the message, which 5963 // will be handled in completeRemoveProvider(). 5964 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5965 } else { 5966 unstableDelta = 0; 5967 } 5968 try { 5969 if (DEBUG_PROVIDER) { 5970 Slog.v(TAG, "incProviderRef Now stable - " 5971 + prc.holder.info.name + ": unstableDelta=" 5972 + unstableDelta); 5973 } 5974 ActivityManager.getService().refContentProvider( 5975 prc.holder.connection, 1, unstableDelta); 5976 } catch (RemoteException e) { 5977 //do nothing content provider object is dead any way 5978 } 5979 } 5980 } else { 5981 prc.unstableCount += 1; 5982 if (prc.unstableCount == 1) { 5983 // We are acquiring a new unstable reference on the provider. 5984 if (prc.removePending) { 5985 // Oh look, we actually have a remove pending for the 5986 // provider, which is still holding the last unstable 5987 // reference. We just need to cancel that to take new 5988 // ownership of the reference. 5989 if (DEBUG_PROVIDER) { 5990 Slog.v(TAG, "incProviderRef: unstable " 5991 + "snatched provider from the jaws of death"); 5992 } 5993 prc.removePending = false; 5994 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5995 } else { 5996 // First unstable ref, increment our count in the 5997 // activity manager. 5998 try { 5999 if (DEBUG_PROVIDER) { 6000 Slog.v(TAG, "incProviderRef: Now unstable - " 6001 + prc.holder.info.name); 6002 } 6003 ActivityManager.getService().refContentProvider( 6004 prc.holder.connection, 0, 1); 6005 } catch (RemoteException e) { 6006 //do nothing content provider object is dead any way 6007 } 6008 } 6009 } 6010 } 6011 } 6012 6013 public final IContentProvider acquireExistingProvider( 6014 Context c, String auth, int userId, boolean stable) { 6015 synchronized (mProviderMap) { 6016 final ProviderKey key = new ProviderKey(auth, userId); 6017 final ProviderClientRecord pr = mProviderMap.get(key); 6018 if (pr == null) { 6019 return null; 6020 } 6021 6022 IContentProvider provider = pr.mProvider; 6023 IBinder jBinder = provider.asBinder(); 6024 if (!jBinder.isBinderAlive()) { 6025 // The hosting process of the provider has died; we can't 6026 // use this one. 6027 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 6028 + ": existing object's process dead"); 6029 handleUnstableProviderDiedLocked(jBinder, true); 6030 return null; 6031 } 6032 6033 // Only increment the ref count if we have one. If we don't then the 6034 // provider is not reference counted and never needs to be released. 6035 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 6036 if (prc != null) { 6037 incProviderRefLocked(prc, stable); 6038 } 6039 return provider; 6040 } 6041 } 6042 6043 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 6044 if (provider == null) { 6045 return false; 6046 } 6047 6048 IBinder jBinder = provider.asBinder(); 6049 synchronized (mProviderMap) { 6050 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 6051 if (prc == null) { 6052 // The provider has no ref count, no release is needed. 6053 return false; 6054 } 6055 6056 boolean lastRef = false; 6057 if (stable) { 6058 if (prc.stableCount == 0) { 6059 if (DEBUG_PROVIDER) Slog.v(TAG, 6060 "releaseProvider: stable ref count already 0, how?"); 6061 return false; 6062 } 6063 prc.stableCount -= 1; 6064 if (prc.stableCount == 0) { 6065 // What we do at this point depends on whether there are 6066 // any unstable refs left: if there are, we just tell the 6067 // activity manager to decrement its stable count; if there 6068 // aren't, we need to enqueue this provider to be removed, 6069 // and convert to holding a single unstable ref while 6070 // doing so. 6071 lastRef = prc.unstableCount == 0; 6072 try { 6073 if (DEBUG_PROVIDER) { 6074 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 6075 + lastRef + " - " + prc.holder.info.name); 6076 } 6077 ActivityManager.getService().refContentProvider( 6078 prc.holder.connection, -1, lastRef ? 1 : 0); 6079 } catch (RemoteException e) { 6080 //do nothing content provider object is dead any way 6081 } 6082 } 6083 } else { 6084 if (prc.unstableCount == 0) { 6085 if (DEBUG_PROVIDER) Slog.v(TAG, 6086 "releaseProvider: unstable ref count already 0, how?"); 6087 return false; 6088 } 6089 prc.unstableCount -= 1; 6090 if (prc.unstableCount == 0) { 6091 // If this is the last reference, we need to enqueue 6092 // this provider to be removed instead of telling the 6093 // activity manager to remove it at this point. 6094 lastRef = prc.stableCount == 0; 6095 if (!lastRef) { 6096 try { 6097 if (DEBUG_PROVIDER) { 6098 Slog.v(TAG, "releaseProvider: No longer unstable - " 6099 + prc.holder.info.name); 6100 } 6101 ActivityManager.getService().refContentProvider( 6102 prc.holder.connection, 0, -1); 6103 } catch (RemoteException e) { 6104 //do nothing content provider object is dead any way 6105 } 6106 } 6107 } 6108 } 6109 6110 if (lastRef) { 6111 if (!prc.removePending) { 6112 // Schedule the actual remove asynchronously, since we don't know the context 6113 // this will be called in. 6114 // TODO: it would be nice to post a delayed message, so 6115 // if we come back and need the same provider quickly 6116 // we will still have it available. 6117 if (DEBUG_PROVIDER) { 6118 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 6119 + prc.holder.info.name); 6120 } 6121 prc.removePending = true; 6122 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 6123 mH.sendMessage(msg); 6124 } else { 6125 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 6126 } 6127 } 6128 return true; 6129 } 6130 } 6131 6132 final void completeRemoveProvider(ProviderRefCount prc) { 6133 synchronized (mProviderMap) { 6134 if (!prc.removePending) { 6135 // There was a race! Some other client managed to acquire 6136 // the provider before the removal was completed. 6137 // Abort the removal. We will do it later. 6138 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 6139 + "provider still in use"); 6140 return; 6141 } 6142 6143 // More complicated race!! Some client managed to acquire the 6144 // provider and release it before the removal was completed. 6145 // Continue the removal, and abort the next remove message. 6146 prc.removePending = false; 6147 6148 final IBinder jBinder = prc.holder.provider.asBinder(); 6149 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 6150 if (existingPrc == prc) { 6151 mProviderRefCountMap.remove(jBinder); 6152 } 6153 6154 for (int i=mProviderMap.size()-1; i>=0; i--) { 6155 ProviderClientRecord pr = mProviderMap.valueAt(i); 6156 IBinder myBinder = pr.mProvider.asBinder(); 6157 if (myBinder == jBinder) { 6158 mProviderMap.removeAt(i); 6159 } 6160 } 6161 } 6162 6163 try { 6164 if (DEBUG_PROVIDER) { 6165 Slog.v(TAG, "removeProvider: Invoking ActivityManagerService." 6166 + "removeContentProvider(" + prc.holder.info.name + ")"); 6167 } 6168 ActivityManager.getService().removeContentProvider( 6169 prc.holder.connection, false); 6170 } catch (RemoteException e) { 6171 //do nothing content provider object is dead any way 6172 } 6173 } 6174 6175 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 6176 synchronized (mProviderMap) { 6177 handleUnstableProviderDiedLocked(provider, fromClient); 6178 } 6179 } 6180 6181 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 6182 ProviderRefCount prc = mProviderRefCountMap.get(provider); 6183 if (prc != null) { 6184 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 6185 + provider + " " + prc.holder.info.name); 6186 mProviderRefCountMap.remove(provider); 6187 for (int i=mProviderMap.size()-1; i>=0; i--) { 6188 ProviderClientRecord pr = mProviderMap.valueAt(i); 6189 if (pr != null && pr.mProvider.asBinder() == provider) { 6190 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 6191 mProviderMap.removeAt(i); 6192 } 6193 } 6194 6195 if (fromClient) { 6196 // We found out about this due to execution in our client 6197 // code. Tell the activity manager about it now, to ensure 6198 // that the next time we go to do anything with the provider 6199 // it knows it is dead (so we don't race with its death 6200 // notification). 6201 try { 6202 ActivityManager.getService().unstableProviderDied( 6203 prc.holder.connection); 6204 } catch (RemoteException e) { 6205 //do nothing content provider object is dead any way 6206 } 6207 } 6208 } 6209 } 6210 6211 final void appNotRespondingViaProvider(IBinder provider) { 6212 synchronized (mProviderMap) { 6213 ProviderRefCount prc = mProviderRefCountMap.get(provider); 6214 if (prc != null) { 6215 try { 6216 ActivityManager.getService() 6217 .appNotRespondingViaProvider(prc.holder.connection); 6218 } catch (RemoteException e) { 6219 throw e.rethrowFromSystemServer(); 6220 } 6221 } 6222 } 6223 } 6224 6225 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 6226 ContentProvider localProvider, ContentProviderHolder holder) { 6227 final String auths[] = holder.info.authority.split(";"); 6228 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 6229 6230 if (provider != null) { 6231 // If this provider is hosted by the core OS and cannot be upgraded, 6232 // then I guess we're okay doing blocking calls to it. 6233 for (String auth : auths) { 6234 switch (auth) { 6235 case ContactsContract.AUTHORITY: 6236 case CallLog.AUTHORITY: 6237 case CallLog.SHADOW_AUTHORITY: 6238 case BlockedNumberContract.AUTHORITY: 6239 case CalendarContract.AUTHORITY: 6240 case Downloads.Impl.AUTHORITY: 6241 case "telephony": 6242 Binder.allowBlocking(provider.asBinder()); 6243 } 6244 } 6245 } 6246 6247 final ProviderClientRecord pcr = new ProviderClientRecord( 6248 auths, provider, localProvider, holder); 6249 for (String auth : auths) { 6250 final ProviderKey key = new ProviderKey(auth, userId); 6251 final ProviderClientRecord existing = mProviderMap.get(key); 6252 if (existing != null) { 6253 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 6254 + " already published as " + auth); 6255 } else { 6256 mProviderMap.put(key, pcr); 6257 } 6258 } 6259 return pcr; 6260 } 6261 6262 /** 6263 * Installs the provider. 6264 * 6265 * Providers that are local to the process or that come from the system server 6266 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 6267 * Other remote providers are reference counted. The initial reference count 6268 * for all reference counted providers is one. Providers that are not reference 6269 * counted do not have a reference count (at all). 6270 * 6271 * This method detects when a provider has already been installed. When this happens, 6272 * it increments the reference count of the existing provider (if appropriate) 6273 * and returns the existing provider. This can happen due to concurrent 6274 * attempts to acquire the same provider. 6275 */ 6276 private ContentProviderHolder installProvider(Context context, 6277 ContentProviderHolder holder, ProviderInfo info, 6278 boolean noisy, boolean noReleaseNeeded, boolean stable) { 6279 ContentProvider localProvider = null; 6280 IContentProvider provider; 6281 if (holder == null || holder.provider == null) { 6282 if (DEBUG_PROVIDER || noisy) { 6283 Slog.d(TAG, "Loading provider " + info.authority + ": " 6284 + info.name); 6285 } 6286 Context c = null; 6287 ApplicationInfo ai = info.applicationInfo; 6288 if (context.getPackageName().equals(ai.packageName)) { 6289 c = context; 6290 } else if (mInitialApplication != null && 6291 mInitialApplication.getPackageName().equals(ai.packageName)) { 6292 c = mInitialApplication; 6293 } else { 6294 try { 6295 c = context.createPackageContext(ai.packageName, 6296 Context.CONTEXT_INCLUDE_CODE); 6297 } catch (PackageManager.NameNotFoundException e) { 6298 // Ignore 6299 } 6300 } 6301 if (c == null) { 6302 Slog.w(TAG, "Unable to get context for package " + 6303 ai.packageName + 6304 " while loading content provider " + 6305 info.name); 6306 return null; 6307 } 6308 6309 if (info.splitName != null) { 6310 try { 6311 c = c.createContextForSplit(info.splitName); 6312 } catch (NameNotFoundException e) { 6313 throw new RuntimeException(e); 6314 } 6315 } 6316 6317 try { 6318 final java.lang.ClassLoader cl = c.getClassLoader(); 6319 LoadedApk packageInfo = peekPackageInfo(ai.packageName, true); 6320 if (packageInfo == null) { 6321 // System startup case. 6322 packageInfo = getSystemContext().mPackageInfo; 6323 } 6324 localProvider = packageInfo.getAppFactory() 6325 .instantiateProvider(cl, info.name); 6326 provider = localProvider.getIContentProvider(); 6327 if (provider == null) { 6328 Slog.e(TAG, "Failed to instantiate class " + 6329 info.name + " from sourceDir " + 6330 info.applicationInfo.sourceDir); 6331 return null; 6332 } 6333 if (DEBUG_PROVIDER) Slog.v( 6334 TAG, "Instantiating local provider " + info.name); 6335 // XXX Need to create the correct context for this provider. 6336 localProvider.attachInfo(c, info); 6337 } catch (java.lang.Exception e) { 6338 if (!mInstrumentation.onException(null, e)) { 6339 throw new RuntimeException( 6340 "Unable to get provider " + info.name 6341 + ": " + e.toString(), e); 6342 } 6343 return null; 6344 } 6345 } else { 6346 provider = holder.provider; 6347 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 6348 + info.name); 6349 } 6350 6351 ContentProviderHolder retHolder; 6352 6353 synchronized (mProviderMap) { 6354 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 6355 + " / " + info.name); 6356 IBinder jBinder = provider.asBinder(); 6357 if (localProvider != null) { 6358 ComponentName cname = new ComponentName(info.packageName, info.name); 6359 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 6360 if (pr != null) { 6361 if (DEBUG_PROVIDER) { 6362 Slog.v(TAG, "installProvider: lost the race, " 6363 + "using existing local provider"); 6364 } 6365 provider = pr.mProvider; 6366 } else { 6367 holder = new ContentProviderHolder(info); 6368 holder.provider = provider; 6369 holder.noReleaseNeeded = true; 6370 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 6371 mLocalProviders.put(jBinder, pr); 6372 mLocalProvidersByName.put(cname, pr); 6373 } 6374 retHolder = pr.mHolder; 6375 } else { 6376 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 6377 if (prc != null) { 6378 if (DEBUG_PROVIDER) { 6379 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 6380 } 6381 // We need to transfer our new reference to the existing 6382 // ref count, releasing the old one... but only if 6383 // release is needed (that is, it is not running in the 6384 // system process). 6385 if (!noReleaseNeeded) { 6386 incProviderRefLocked(prc, stable); 6387 try { 6388 ActivityManager.getService().removeContentProvider( 6389 holder.connection, stable); 6390 } catch (RemoteException e) { 6391 //do nothing content provider object is dead any way 6392 } 6393 } 6394 } else { 6395 ProviderClientRecord client = installProviderAuthoritiesLocked( 6396 provider, localProvider, holder); 6397 if (noReleaseNeeded) { 6398 prc = new ProviderRefCount(holder, client, 1000, 1000); 6399 } else { 6400 prc = stable 6401 ? new ProviderRefCount(holder, client, 1, 0) 6402 : new ProviderRefCount(holder, client, 0, 1); 6403 } 6404 mProviderRefCountMap.put(jBinder, prc); 6405 } 6406 retHolder = prc.holder; 6407 } 6408 } 6409 return retHolder; 6410 } 6411 6412 private void handleRunIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) { 6413 try { 6414 Method main = Class.forName(entryPoint).getMethod("main", String[].class); 6415 main.invoke(null, new Object[]{entryPointArgs}); 6416 } catch (ReflectiveOperationException e) { 6417 throw new AndroidRuntimeException("runIsolatedEntryPoint failed", e); 6418 } 6419 // The process will be empty after this method returns; exit the VM now. 6420 System.exit(0); 6421 } 6422 6423 private void attach(boolean system, long startSeq) { 6424 sCurrentActivityThread = this; 6425 mSystemThread = system; 6426 if (!system) { 6427 ViewRootImpl.addFirstDrawHandler(new Runnable() { 6428 @Override 6429 public void run() { 6430 ensureJitEnabled(); 6431 } 6432 }); 6433 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 6434 UserHandle.myUserId()); 6435 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 6436 final IActivityManager mgr = ActivityManager.getService(); 6437 try { 6438 mgr.attachApplication(mAppThread, startSeq); 6439 } catch (RemoteException ex) { 6440 throw ex.rethrowFromSystemServer(); 6441 } 6442 // Watch for getting close to heap limit. 6443 BinderInternal.addGcWatcher(new Runnable() { 6444 @Override public void run() { 6445 if (!mSomeActivitiesChanged) { 6446 return; 6447 } 6448 Runtime runtime = Runtime.getRuntime(); 6449 long dalvikMax = runtime.maxMemory(); 6450 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); 6451 if (dalvikUsed > ((3*dalvikMax)/4)) { 6452 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) 6453 + " total=" + (runtime.totalMemory()/1024) 6454 + " used=" + (dalvikUsed/1024)); 6455 mSomeActivitiesChanged = false; 6456 try { 6457 mgr.releaseSomeActivities(mAppThread); 6458 } catch (RemoteException e) { 6459 throw e.rethrowFromSystemServer(); 6460 } 6461 } 6462 } 6463 }); 6464 } else { 6465 // Don't set application object here -- if the system crashes, 6466 // we can't display an alert, we just want to die die die. 6467 android.ddm.DdmHandleAppName.setAppName("system_process", 6468 UserHandle.myUserId()); 6469 try { 6470 mInstrumentation = new Instrumentation(); 6471 mInstrumentation.basicInit(this); 6472 ContextImpl context = ContextImpl.createAppContext( 6473 this, getSystemContext().mPackageInfo); 6474 mInitialApplication = context.mPackageInfo.makeApplication(true, null); 6475 mInitialApplication.onCreate(); 6476 } catch (Exception e) { 6477 throw new RuntimeException( 6478 "Unable to instantiate Application():" + e.toString(), e); 6479 } 6480 } 6481 6482 // add dropbox logging to libcore 6483 DropBox.setReporter(new DropBoxReporter()); 6484 6485 ViewRootImpl.ConfigChangedCallback configChangedCallback 6486 = (Configuration globalConfig) -> { 6487 synchronized (mResourcesManager) { 6488 // We need to apply this change to the resources immediately, because upon returning 6489 // the view hierarchy will be informed about it. 6490 if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig, 6491 null /* compat */)) { 6492 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), 6493 mResourcesManager.getConfiguration().getLocales()); 6494 6495 // This actually changed the resources! Tell everyone about it. 6496 if (mPendingConfiguration == null 6497 || mPendingConfiguration.isOtherSeqNewer(globalConfig)) { 6498 mPendingConfiguration = globalConfig; 6499 sendMessage(H.CONFIGURATION_CHANGED, globalConfig); 6500 } 6501 } 6502 } 6503 }; 6504 ViewRootImpl.addConfigCallback(configChangedCallback); 6505 } 6506 6507 public static ActivityThread systemMain() { 6508 // The system process on low-memory devices do not get to use hardware 6509 // accelerated drawing, since this can add too much overhead to the 6510 // process. 6511 if (!ActivityManager.isHighEndGfx()) { 6512 ThreadedRenderer.disable(true); 6513 } else { 6514 ThreadedRenderer.enableForegroundTrimming(); 6515 } 6516 ActivityThread thread = new ActivityThread(); 6517 thread.attach(true, 0); 6518 return thread; 6519 } 6520 6521 public final void installSystemProviders(List<ProviderInfo> providers) { 6522 if (providers != null) { 6523 installContentProviders(mInitialApplication, providers); 6524 } 6525 } 6526 6527 public int getIntCoreSetting(String key, int defaultValue) { 6528 synchronized (mResourcesManager) { 6529 if (mCoreSettings != null) { 6530 return mCoreSettings.getInt(key, defaultValue); 6531 } 6532 return defaultValue; 6533 } 6534 } 6535 6536 private static class EventLoggingReporter implements EventLogger.Reporter { 6537 @Override 6538 public void report (int code, Object... list) { 6539 EventLog.writeEvent(code, list); 6540 } 6541 } 6542 6543 private class DropBoxReporter implements DropBox.Reporter { 6544 6545 private DropBoxManager dropBox; 6546 6547 public DropBoxReporter() {} 6548 6549 @Override 6550 public void addData(String tag, byte[] data, int flags) { 6551 ensureInitialized(); 6552 dropBox.addData(tag, data, flags); 6553 } 6554 6555 @Override 6556 public void addText(String tag, String data) { 6557 ensureInitialized(); 6558 dropBox.addText(tag, data); 6559 } 6560 6561 private synchronized void ensureInitialized() { 6562 if (dropBox == null) { 6563 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 6564 } 6565 } 6566 } 6567 6568 public static void main(String[] args) { 6569 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); 6570 6571 // CloseGuard defaults to true and can be quite spammy. We 6572 // disable it here, but selectively enable it later (via 6573 // StrictMode) on debug builds, but using DropBox, not logs. 6574 CloseGuard.setEnabled(false); 6575 6576 Environment.initForCurrentUser(); 6577 6578 // Set the reporter for event logging in libcore 6579 EventLogger.setReporter(new EventLoggingReporter()); 6580 6581 // Make sure TrustedCertificateStore looks in the right place for CA certificates 6582 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); 6583 TrustedCertificateStore.setDefaultUserDirectory(configDir); 6584 6585 Process.setArgV0("<pre-initialized>"); 6586 6587 Looper.prepareMainLooper(); 6588 6589 // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line. 6590 // It will be in the format "seq=114" 6591 long startSeq = 0; 6592 if (args != null) { 6593 for (int i = args.length - 1; i >= 0; --i) { 6594 if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) { 6595 startSeq = Long.parseLong( 6596 args[i].substring(PROC_START_SEQ_IDENT.length())); 6597 } 6598 } 6599 } 6600 ActivityThread thread = new ActivityThread(); 6601 thread.attach(false, startSeq); 6602 6603 if (sMainThreadHandler == null) { 6604 sMainThreadHandler = thread.getHandler(); 6605 } 6606 6607 if (false) { 6608 Looper.myLooper().setMessageLogging(new 6609 LogPrinter(Log.DEBUG, "ActivityThread")); 6610 } 6611 6612 // End of event ActivityThreadMain. 6613 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 6614 Looper.loop(); 6615 6616 throw new RuntimeException("Main thread loop unexpectedly exited"); 6617 } 6618 6619 // ------------------ Regular JNI ------------------------ 6620 6621 private native void nDumpGraphicsInfo(FileDescriptor fd); 6622} 6623