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