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