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