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