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