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