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