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