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