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