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