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