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