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