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