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