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