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