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