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