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