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