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