ActivityThread.java revision 77bdfb512f963701082c5c78e9a9db00b167fcb6
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 // Normally the ViewRoot sets up callbacks with the Activity 3478 // in addView->ViewRootImpl#setView. If we are instead reusing 3479 // the decor view we have to notify the view root that the 3480 // callbacks may have changed. 3481 ViewRootImpl impl = decor.getViewRootImpl(); 3482 if (impl != null) { 3483 impl.notifyChildRebuilt(); 3484 } 3485 } 3486 if (a.mVisibleFromClient && !a.mWindowAdded) { 3487 a.mWindowAdded = true; 3488 wm.addView(decor, l); 3489 } 3490 3491 // If the window has already been added, but during resume 3492 // we started another activity, then don't yet make the 3493 // window visible. 3494 } else if (!willBeVisible) { 3495 if (localLOGV) Slog.v( 3496 TAG, "Launch " + r + " mStartedActivity set"); 3497 r.hideForNow = true; 3498 } 3499 3500 // Get rid of anything left hanging around. 3501 cleanUpPendingRemoveWindows(r, false /* force */); 3502 3503 // The window is now visible if it has been added, we are not 3504 // simply finishing, and we are not starting another activity. 3505 if (!r.activity.mFinished && willBeVisible 3506 && r.activity.mDecor != null && !r.hideForNow) { 3507 if (r.newConfig != null) { 3508 performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY); 3509 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 3510 + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig); 3511 r.newConfig = null; 3512 } 3513 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 3514 + isForward); 3515 WindowManager.LayoutParams l = r.window.getAttributes(); 3516 if ((l.softInputMode 3517 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 3518 != forwardBit) { 3519 l.softInputMode = (l.softInputMode 3520 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 3521 | forwardBit; 3522 if (r.activity.mVisibleFromClient) { 3523 ViewManager wm = a.getWindowManager(); 3524 View decor = r.window.getDecorView(); 3525 wm.updateViewLayout(decor, l); 3526 } 3527 } 3528 r.activity.mVisibleFromServer = true; 3529 mNumVisibleActivities++; 3530 if (r.activity.mVisibleFromClient) { 3531 r.activity.makeVisible(); 3532 } 3533 } 3534 3535 if (!r.onlyLocalRequest) { 3536 r.nextIdle = mNewActivities; 3537 mNewActivities = r; 3538 if (localLOGV) Slog.v( 3539 TAG, "Scheduling idle handler for " + r); 3540 Looper.myQueue().addIdleHandler(new Idler()); 3541 } 3542 r.onlyLocalRequest = false; 3543 3544 // Tell the activity manager we have resumed. 3545 if (reallyResume) { 3546 try { 3547 ActivityManagerNative.getDefault().activityResumed(token); 3548 } catch (RemoteException ex) { 3549 throw ex.rethrowFromSystemServer(); 3550 } 3551 } 3552 3553 } else { 3554 // If an exception was thrown when trying to resume, then 3555 // just end this activity. 3556 try { 3557 ActivityManagerNative.getDefault() 3558 .finishActivity(token, Activity.RESULT_CANCELED, null, 3559 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 3560 } catch (RemoteException ex) { 3561 throw ex.rethrowFromSystemServer(); 3562 } 3563 } 3564 } 3565 3566 private int mThumbnailWidth = -1; 3567 private int mThumbnailHeight = -1; 3568 private Bitmap mAvailThumbnailBitmap = null; 3569 private Canvas mThumbnailCanvas = null; 3570 3571 private Bitmap createThumbnailBitmap(ActivityClientRecord r) { 3572 Bitmap thumbnail = mAvailThumbnailBitmap; 3573 try { 3574 if (thumbnail == null) { 3575 int w = mThumbnailWidth; 3576 int h; 3577 if (w < 0) { 3578 Resources res = r.activity.getResources(); 3579 int wId = com.android.internal.R.dimen.thumbnail_width; 3580 int hId = com.android.internal.R.dimen.thumbnail_height; 3581 mThumbnailWidth = w = res.getDimensionPixelSize(wId); 3582 mThumbnailHeight = h = res.getDimensionPixelSize(hId); 3583 } else { 3584 h = mThumbnailHeight; 3585 } 3586 3587 // On platforms where we don't want thumbnails, set dims to (0,0) 3588 if ((w > 0) && (h > 0)) { 3589 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 3590 w, h, THUMBNAIL_FORMAT); 3591 thumbnail.eraseColor(0); 3592 } 3593 } 3594 3595 if (thumbnail != null) { 3596 Canvas cv = mThumbnailCanvas; 3597 if (cv == null) { 3598 mThumbnailCanvas = cv = new Canvas(); 3599 } 3600 3601 cv.setBitmap(thumbnail); 3602 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 3603 mAvailThumbnailBitmap = thumbnail; 3604 thumbnail = null; 3605 } 3606 cv.setBitmap(null); 3607 } 3608 3609 } catch (Exception e) { 3610 if (!mInstrumentation.onException(r.activity, e)) { 3611 throw new RuntimeException( 3612 "Unable to create thumbnail of " 3613 + r.intent.getComponent().toShortString() 3614 + ": " + e.toString(), e); 3615 } 3616 thumbnail = null; 3617 } 3618 3619 return thumbnail; 3620 } 3621 3622 private void handlePauseActivity(IBinder token, boolean finished, 3623 boolean userLeaving, int configChanges, boolean dontReport, int seq) { 3624 ActivityClientRecord r = mActivities.get(token); 3625 if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq); 3626 if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) { 3627 return; 3628 } 3629 if (r != null) { 3630 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 3631 if (userLeaving) { 3632 performUserLeavingActivity(r); 3633 } 3634 3635 r.activity.mConfigChangeFlags |= configChanges; 3636 performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity"); 3637 3638 // Make sure any pending writes are now committed. 3639 if (r.isPreHoneycomb()) { 3640 QueuedWork.waitToFinish(); 3641 } 3642 3643 // Tell the activity manager we have paused. 3644 if (!dontReport) { 3645 try { 3646 ActivityManagerNative.getDefault().activityPaused(token); 3647 } catch (RemoteException ex) { 3648 throw ex.rethrowFromSystemServer(); 3649 } 3650 } 3651 mSomeActivitiesChanged = true; 3652 } 3653 } 3654 3655 final void performUserLeavingActivity(ActivityClientRecord r) { 3656 mInstrumentation.callActivityOnUserLeaving(r.activity); 3657 } 3658 3659 final Bundle performPauseActivity(IBinder token, boolean finished, 3660 boolean saveState, String reason) { 3661 ActivityClientRecord r = mActivities.get(token); 3662 return r != null ? performPauseActivity(r, finished, saveState, reason) : null; 3663 } 3664 3665 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 3666 boolean saveState, String reason) { 3667 if (r.paused) { 3668 if (r.activity.mFinished) { 3669 // If we are finishing, we won't call onResume() in certain cases. 3670 // So here we likewise don't want to call onPause() if the activity 3671 // isn't resumed. 3672 return null; 3673 } 3674 RuntimeException e = new RuntimeException( 3675 "Performing pause of activity that is not resumed: " 3676 + r.intent.getComponent().toShortString()); 3677 Slog.e(TAG, e.getMessage(), e); 3678 } 3679 if (finished) { 3680 r.activity.mFinished = true; 3681 } 3682 try { 3683 // Next have the activity save its current state and managed dialogs... 3684 if (!r.activity.mFinished && saveState) { 3685 callCallActivityOnSaveInstanceState(r); 3686 } 3687 // Now we are idle. 3688 r.activity.mCalled = false; 3689 mInstrumentation.callActivityOnPause(r.activity); 3690 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), 3691 r.activity.getComponentName().getClassName(), reason); 3692 if (!r.activity.mCalled) { 3693 throw new SuperNotCalledException( 3694 "Activity " + r.intent.getComponent().toShortString() + 3695 " did not call through to super.onPause()"); 3696 } 3697 3698 } catch (SuperNotCalledException e) { 3699 throw e; 3700 3701 } catch (Exception e) { 3702 if (!mInstrumentation.onException(r.activity, e)) { 3703 throw new RuntimeException( 3704 "Unable to pause activity " 3705 + r.intent.getComponent().toShortString() 3706 + ": " + e.toString(), e); 3707 } 3708 } 3709 r.paused = true; 3710 3711 // Notify any outstanding on paused listeners 3712 ArrayList<OnActivityPausedListener> listeners; 3713 synchronized (mOnPauseListeners) { 3714 listeners = mOnPauseListeners.remove(r.activity); 3715 } 3716 int size = (listeners != null ? listeners.size() : 0); 3717 for (int i = 0; i < size; i++) { 3718 listeners.get(i).onPaused(r.activity); 3719 } 3720 3721 return !r.activity.mFinished && saveState ? r.state : null; 3722 } 3723 3724 final void performStopActivity(IBinder token, boolean saveState, String reason) { 3725 ActivityClientRecord r = mActivities.get(token); 3726 performStopActivityInner(r, null, false, saveState, reason); 3727 } 3728 3729 private static class StopInfo implements Runnable { 3730 ActivityClientRecord activity; 3731 Bundle state; 3732 PersistableBundle persistentState; 3733 CharSequence description; 3734 3735 @Override public void run() { 3736 // Tell activity manager we have been stopped. 3737 try { 3738 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3739 ActivityManagerNative.getDefault().activityStopped( 3740 activity.token, state, persistentState, description); 3741 } catch (RemoteException ex) { 3742 if (ex instanceof TransactionTooLargeException 3743 && activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) { 3744 Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex); 3745 return; 3746 } 3747 throw ex.rethrowFromSystemServer(); 3748 } 3749 } 3750 } 3751 3752 private static final class ProviderRefCount { 3753 public final IActivityManager.ContentProviderHolder holder; 3754 public final ProviderClientRecord client; 3755 public int stableCount; 3756 public int unstableCount; 3757 3758 // When this is set, the stable and unstable ref counts are 0 and 3759 // we have a pending operation scheduled to remove the ref count 3760 // from the activity manager. On the activity manager we are still 3761 // holding an unstable ref, though it is not reflected in the counts 3762 // here. 3763 public boolean removePending; 3764 3765 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder, 3766 ProviderClientRecord inClient, int sCount, int uCount) { 3767 holder = inHolder; 3768 client = inClient; 3769 stableCount = sCount; 3770 unstableCount = uCount; 3771 } 3772 } 3773 3774 /** 3775 * Core implementation of stopping an activity. Note this is a little 3776 * tricky because the server's meaning of stop is slightly different 3777 * than our client -- for the server, stop means to save state and give 3778 * it the result when it is done, but the window may still be visible. 3779 * For the client, we want to call onStop()/onStart() to indicate when 3780 * the activity's UI visibillity changes. 3781 */ 3782 private void performStopActivityInner(ActivityClientRecord r, 3783 StopInfo info, boolean keepShown, boolean saveState, String reason) { 3784 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3785 if (r != null) { 3786 if (!keepShown && r.stopped) { 3787 if (r.activity.mFinished) { 3788 // If we are finishing, we won't call onResume() in certain 3789 // cases. So here we likewise don't want to call onStop() 3790 // if the activity isn't resumed. 3791 return; 3792 } 3793 RuntimeException e = new RuntimeException( 3794 "Performing stop of activity that is already stopped: " 3795 + r.intent.getComponent().toShortString()); 3796 Slog.e(TAG, e.getMessage(), e); 3797 Slog.e(TAG, r.getStateString()); 3798 } 3799 3800 if (info != null) { 3801 try { 3802 // First create a thumbnail for the activity... 3803 // For now, don't create the thumbnail here; we are 3804 // doing that by doing a screen snapshot. 3805 info.description = r.activity.onCreateDescription(); 3806 } catch (Exception e) { 3807 if (!mInstrumentation.onException(r.activity, e)) { 3808 throw new RuntimeException( 3809 "Unable to save state of activity " 3810 + r.intent.getComponent().toShortString() 3811 + ": " + e.toString(), e); 3812 } 3813 } 3814 } 3815 3816 // Next have the activity save its current state and managed dialogs... 3817 if (!r.activity.mFinished && saveState) { 3818 if (r.state == null) { 3819 callCallActivityOnSaveInstanceState(r); 3820 } 3821 } 3822 3823 if (!keepShown) { 3824 try { 3825 // Now we are idle. 3826 r.activity.performStop(false /*preserveWindow*/); 3827 } catch (Exception e) { 3828 if (!mInstrumentation.onException(r.activity, e)) { 3829 throw new RuntimeException( 3830 "Unable to stop activity " 3831 + r.intent.getComponent().toShortString() 3832 + ": " + e.toString(), e); 3833 } 3834 } 3835 r.stopped = true; 3836 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(), 3837 r.activity.getComponentName().getClassName(), reason); 3838 } 3839 3840 r.paused = true; 3841 } 3842 } 3843 3844 private void updateVisibility(ActivityClientRecord r, boolean show) { 3845 View v = r.activity.mDecor; 3846 if (v != null) { 3847 if (show) { 3848 if (!r.activity.mVisibleFromServer) { 3849 r.activity.mVisibleFromServer = true; 3850 mNumVisibleActivities++; 3851 if (r.activity.mVisibleFromClient) { 3852 r.activity.makeVisible(); 3853 } 3854 } 3855 if (r.newConfig != null) { 3856 performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY); 3857 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 3858 + r.activityInfo.name + " with new config " 3859 + r.activity.mCurrentConfig); 3860 r.newConfig = null; 3861 } 3862 } else { 3863 if (r.activity.mVisibleFromServer) { 3864 r.activity.mVisibleFromServer = false; 3865 mNumVisibleActivities--; 3866 v.setVisibility(View.INVISIBLE); 3867 } 3868 } 3869 } 3870 } 3871 3872 private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) { 3873 ActivityClientRecord r = mActivities.get(token); 3874 if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) { 3875 return; 3876 } 3877 r.activity.mConfigChangeFlags |= configChanges; 3878 3879 StopInfo info = new StopInfo(); 3880 performStopActivityInner(r, info, show, true, "handleStopActivity"); 3881 3882 if (localLOGV) Slog.v( 3883 TAG, "Finishing stop of " + r + ": show=" + show 3884 + " win=" + r.window); 3885 3886 updateVisibility(r, show); 3887 3888 // Make sure any pending writes are now committed. 3889 if (!r.isPreHoneycomb()) { 3890 QueuedWork.waitToFinish(); 3891 } 3892 3893 // Schedule the call to tell the activity manager we have 3894 // stopped. We don't do this immediately, because we want to 3895 // have a chance for any other pending work (in particular memory 3896 // trim requests) to complete before you tell the activity 3897 // manager to proceed and allow us to go fully into the background. 3898 info.activity = r; 3899 info.state = r.state; 3900 info.persistentState = r.persistentState; 3901 mH.post(info); 3902 mSomeActivitiesChanged = true; 3903 } 3904 3905 private static boolean checkAndUpdateLifecycleSeq(int seq, ActivityClientRecord r, 3906 String action) { 3907 if (r == null) { 3908 return true; 3909 } 3910 if (seq < r.lastProcessedSeq) { 3911 if (DEBUG_ORDER) Slog.d(TAG, action + " for " + r + " ignored, because seq=" + seq 3912 + " < mCurrentLifecycleSeq=" + r.lastProcessedSeq); 3913 return false; 3914 } 3915 r.lastProcessedSeq = seq; 3916 return true; 3917 } 3918 3919 final void performRestartActivity(IBinder token) { 3920 ActivityClientRecord r = mActivities.get(token); 3921 if (r.stopped) { 3922 r.activity.performRestart(); 3923 r.stopped = false; 3924 } 3925 } 3926 3927 private void handleWindowVisibility(IBinder token, boolean show) { 3928 ActivityClientRecord r = mActivities.get(token); 3929 3930 if (r == null) { 3931 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 3932 return; 3933 } 3934 3935 if (!show && !r.stopped) { 3936 performStopActivityInner(r, null, show, false, "handleWindowVisibility"); 3937 } else if (show && r.stopped) { 3938 // If we are getting ready to gc after going to the background, well 3939 // we are back active so skip it. 3940 unscheduleGcIdler(); 3941 3942 r.activity.performRestart(); 3943 r.stopped = false; 3944 } 3945 if (r.activity.mDecor != null) { 3946 if (false) Slog.v( 3947 TAG, "Handle window " + r + " visibility: " + show); 3948 updateVisibility(r, show); 3949 } 3950 mSomeActivitiesChanged = true; 3951 } 3952 3953 private void handleSleeping(IBinder token, boolean sleeping) { 3954 ActivityClientRecord r = mActivities.get(token); 3955 3956 if (r == null) { 3957 Log.w(TAG, "handleSleeping: no activity for token " + token); 3958 return; 3959 } 3960 3961 if (sleeping) { 3962 if (!r.stopped && !r.isPreHoneycomb()) { 3963 try { 3964 // Now we are idle. 3965 r.activity.performStop(false /*preserveWindow*/); 3966 } catch (Exception e) { 3967 if (!mInstrumentation.onException(r.activity, e)) { 3968 throw new RuntimeException( 3969 "Unable to stop activity " 3970 + r.intent.getComponent().toShortString() 3971 + ": " + e.toString(), e); 3972 } 3973 } 3974 r.stopped = true; 3975 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(), 3976 r.activity.getComponentName().getClassName(), "sleeping"); 3977 } 3978 3979 // Make sure any pending writes are now committed. 3980 if (!r.isPreHoneycomb()) { 3981 QueuedWork.waitToFinish(); 3982 } 3983 3984 // Tell activity manager we slept. 3985 try { 3986 ActivityManagerNative.getDefault().activitySlept(r.token); 3987 } catch (RemoteException ex) { 3988 throw ex.rethrowFromSystemServer(); 3989 } 3990 } else { 3991 if (r.stopped && r.activity.mVisibleFromServer) { 3992 r.activity.performRestart(); 3993 r.stopped = false; 3994 } 3995 } 3996 } 3997 3998 private void handleSetCoreSettings(Bundle coreSettings) { 3999 synchronized (mResourcesManager) { 4000 mCoreSettings = coreSettings; 4001 } 4002 onCoreSettingsChange(); 4003 } 4004 4005 private void onCoreSettingsChange() { 4006 boolean debugViewAttributes = 4007 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 4008 if (debugViewAttributes != View.mDebugViewAttributes) { 4009 View.mDebugViewAttributes = debugViewAttributes; 4010 4011 // request all activities to relaunch for the changes to take place 4012 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { 4013 requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false, 4014 false /* preserveWindow */); 4015 } 4016 } 4017 } 4018 4019 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 4020 LoadedApk apk = peekPackageInfo(data.pkg, false); 4021 if (apk != null) { 4022 apk.setCompatibilityInfo(data.info); 4023 } 4024 apk = peekPackageInfo(data.pkg, true); 4025 if (apk != null) { 4026 apk.setCompatibilityInfo(data.info); 4027 } 4028 handleConfigurationChanged(mConfiguration, data.info); 4029 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 4030 } 4031 4032 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 4033 final int N = results.size(); 4034 for (int i=0; i<N; i++) { 4035 ResultInfo ri = results.get(i); 4036 try { 4037 if (ri.mData != null) { 4038 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 4039 ri.mData.prepareToEnterProcess(); 4040 } 4041 if (DEBUG_RESULTS) Slog.v(TAG, 4042 "Delivering result to activity " + r + " : " + ri); 4043 r.activity.dispatchActivityResult(ri.mResultWho, 4044 ri.mRequestCode, ri.mResultCode, ri.mData); 4045 } catch (Exception e) { 4046 if (!mInstrumentation.onException(r.activity, e)) { 4047 throw new RuntimeException( 4048 "Failure delivering result " + ri + " to activity " 4049 + r.intent.getComponent().toShortString() 4050 + ": " + e.toString(), e); 4051 } 4052 } 4053 } 4054 } 4055 4056 private void handleSendResult(ResultData res) { 4057 ActivityClientRecord r = mActivities.get(res.token); 4058 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 4059 if (r != null) { 4060 final boolean resumed = !r.paused; 4061 if (!r.activity.mFinished && r.activity.mDecor != null 4062 && r.hideForNow && resumed) { 4063 // We had hidden the activity because it started another 4064 // one... we have gotten a result back and we are not 4065 // paused, so make sure our window is visible. 4066 updateVisibility(r, true); 4067 } 4068 if (resumed) { 4069 try { 4070 // Now we are idle. 4071 r.activity.mCalled = false; 4072 r.activity.mTemporaryPause = true; 4073 mInstrumentation.callActivityOnPause(r.activity); 4074 if (!r.activity.mCalled) { 4075 throw new SuperNotCalledException( 4076 "Activity " + r.intent.getComponent().toShortString() 4077 + " did not call through to super.onPause()"); 4078 } 4079 } catch (SuperNotCalledException e) { 4080 throw e; 4081 } catch (Exception e) { 4082 if (!mInstrumentation.onException(r.activity, e)) { 4083 throw new RuntimeException( 4084 "Unable to pause activity " 4085 + r.intent.getComponent().toShortString() 4086 + ": " + e.toString(), e); 4087 } 4088 } 4089 } 4090 deliverResults(r, res.results); 4091 if (resumed) { 4092 r.activity.performResume(); 4093 r.activity.mTemporaryPause = false; 4094 } 4095 } 4096 } 4097 4098 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 4099 return performDestroyActivity(token, finishing, 0, false); 4100 } 4101 4102 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 4103 int configChanges, boolean getNonConfigInstance) { 4104 ActivityClientRecord r = mActivities.get(token); 4105 Class<? extends Activity> activityClass = null; 4106 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 4107 if (r != null) { 4108 activityClass = r.activity.getClass(); 4109 r.activity.mConfigChangeFlags |= configChanges; 4110 if (finishing) { 4111 r.activity.mFinished = true; 4112 } 4113 if (!r.paused) { 4114 try { 4115 r.activity.mCalled = false; 4116 mInstrumentation.callActivityOnPause(r.activity); 4117 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), 4118 r.activity.getComponentName().getClassName(), "destroy"); 4119 if (!r.activity.mCalled) { 4120 throw new SuperNotCalledException( 4121 "Activity " + safeToComponentShortString(r.intent) 4122 + " did not call through to super.onPause()"); 4123 } 4124 } catch (SuperNotCalledException e) { 4125 throw e; 4126 } catch (Exception e) { 4127 if (!mInstrumentation.onException(r.activity, e)) { 4128 throw new RuntimeException( 4129 "Unable to pause activity " 4130 + safeToComponentShortString(r.intent) 4131 + ": " + e.toString(), e); 4132 } 4133 } 4134 r.paused = true; 4135 } 4136 if (!r.stopped) { 4137 try { 4138 r.activity.performStop(r.mPreserveWindow); 4139 } catch (SuperNotCalledException e) { 4140 throw e; 4141 } catch (Exception e) { 4142 if (!mInstrumentation.onException(r.activity, e)) { 4143 throw new RuntimeException( 4144 "Unable to stop activity " 4145 + safeToComponentShortString(r.intent) 4146 + ": " + e.toString(), e); 4147 } 4148 } 4149 r.stopped = true; 4150 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(), 4151 r.activity.getComponentName().getClassName(), "destroy"); 4152 } 4153 if (getNonConfigInstance) { 4154 try { 4155 r.lastNonConfigurationInstances 4156 = r.activity.retainNonConfigurationInstances(); 4157 } catch (Exception e) { 4158 if (!mInstrumentation.onException(r.activity, e)) { 4159 throw new RuntimeException( 4160 "Unable to retain activity " 4161 + r.intent.getComponent().toShortString() 4162 + ": " + e.toString(), e); 4163 } 4164 } 4165 } 4166 try { 4167 r.activity.mCalled = false; 4168 mInstrumentation.callActivityOnDestroy(r.activity); 4169 if (!r.activity.mCalled) { 4170 throw new SuperNotCalledException( 4171 "Activity " + safeToComponentShortString(r.intent) + 4172 " did not call through to super.onDestroy()"); 4173 } 4174 if (r.window != null) { 4175 r.window.closeAllPanels(); 4176 } 4177 } catch (SuperNotCalledException e) { 4178 throw e; 4179 } catch (Exception e) { 4180 if (!mInstrumentation.onException(r.activity, e)) { 4181 throw new RuntimeException( 4182 "Unable to destroy activity " + safeToComponentShortString(r.intent) 4183 + ": " + e.toString(), e); 4184 } 4185 } 4186 } 4187 mActivities.remove(token); 4188 StrictMode.decrementExpectedActivityCount(activityClass); 4189 return r; 4190 } 4191 4192 private static String safeToComponentShortString(Intent intent) { 4193 ComponentName component = intent.getComponent(); 4194 return component == null ? "[Unknown]" : component.toShortString(); 4195 } 4196 4197 private void handleDestroyActivity(IBinder token, boolean finishing, 4198 int configChanges, boolean getNonConfigInstance) { 4199 ActivityClientRecord r = performDestroyActivity(token, finishing, 4200 configChanges, getNonConfigInstance); 4201 if (r != null) { 4202 cleanUpPendingRemoveWindows(r, finishing); 4203 WindowManager wm = r.activity.getWindowManager(); 4204 View v = r.activity.mDecor; 4205 if (v != null) { 4206 if (r.activity.mVisibleFromServer) { 4207 mNumVisibleActivities--; 4208 } 4209 IBinder wtoken = v.getWindowToken(); 4210 if (r.activity.mWindowAdded) { 4211 if (r.mPreserveWindow) { 4212 // Hold off on removing this until the new activity's 4213 // window is being added. 4214 r.mPendingRemoveWindow = r.window; 4215 r.mPendingRemoveWindowManager = wm; 4216 if (r.mPreserveWindow) { 4217 // We can only keep the part of the view hierarchy that we control, 4218 // everything else must be removed, because it might not be able to 4219 // behave properly when activity is relaunching. 4220 r.window.clearContentView(); 4221 } 4222 } else { 4223 wm.removeViewImmediate(v); 4224 } 4225 } 4226 if (wtoken != null && r.mPendingRemoveWindow == null) { 4227 WindowManagerGlobal.getInstance().closeAll(wtoken, 4228 r.activity.getClass().getName(), "Activity"); 4229 } 4230 r.activity.mDecor = null; 4231 } 4232 if (r.mPendingRemoveWindow == null) { 4233 // If we are delaying the removal of the activity window, then 4234 // we can't clean up all windows here. Note that we can't do 4235 // so later either, which means any windows that aren't closed 4236 // by the app will leak. Well we try to warning them a lot 4237 // about leaking windows, because that is a bug, so if they are 4238 // using this recreate facility then they get to live with leaks. 4239 WindowManagerGlobal.getInstance().closeAll(token, 4240 r.activity.getClass().getName(), "Activity"); 4241 } 4242 4243 // Mocked out contexts won't be participating in the normal 4244 // process lifecycle, but if we're running with a proper 4245 // ApplicationContext we need to have it tear down things 4246 // cleanly. 4247 Context c = r.activity.getBaseContext(); 4248 if (c instanceof ContextImpl) { 4249 ((ContextImpl) c).scheduleFinalCleanup( 4250 r.activity.getClass().getName(), "Activity"); 4251 } 4252 } 4253 if (finishing) { 4254 try { 4255 ActivityManagerNative.getDefault().activityDestroyed(token); 4256 } catch (RemoteException ex) { 4257 throw ex.rethrowFromSystemServer(); 4258 } 4259 } 4260 mSomeActivitiesChanged = true; 4261 } 4262 4263 /** 4264 * @param preserveWindow Whether the activity should try to reuse the window it created, 4265 * including the decor view after the relaunch. 4266 */ 4267 public final void requestRelaunchActivity(IBinder token, 4268 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 4269 int configChanges, boolean notResumed, Configuration config, 4270 Configuration overrideConfig, boolean fromServer, boolean preserveWindow) { 4271 ActivityClientRecord target = null; 4272 4273 synchronized (mResourcesManager) { 4274 for (int i=0; i<mRelaunchingActivities.size(); i++) { 4275 ActivityClientRecord r = mRelaunchingActivities.get(i); 4276 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r); 4277 if (r.token == token) { 4278 target = r; 4279 if (pendingResults != null) { 4280 if (r.pendingResults != null) { 4281 r.pendingResults.addAll(pendingResults); 4282 } else { 4283 r.pendingResults = pendingResults; 4284 } 4285 } 4286 if (pendingNewIntents != null) { 4287 if (r.pendingIntents != null) { 4288 r.pendingIntents.addAll(pendingNewIntents); 4289 } else { 4290 r.pendingIntents = pendingNewIntents; 4291 } 4292 } 4293 4294 // For each relaunch request, activity manager expects an answer 4295 if (!r.onlyLocalRequest && fromServer) { 4296 try { 4297 ActivityManagerNative.getDefault().activityRelaunched(token); 4298 } catch (RemoteException e) { 4299 throw e.rethrowFromSystemServer(); 4300 } 4301 } 4302 break; 4303 } 4304 } 4305 4306 if (target == null) { 4307 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:" 4308 + fromServer); 4309 target = new ActivityClientRecord(); 4310 target.token = token; 4311 target.pendingResults = pendingResults; 4312 target.pendingIntents = pendingNewIntents; 4313 target.mPreserveWindow = preserveWindow; 4314 if (!fromServer) { 4315 final ActivityClientRecord existing = mActivities.get(token); 4316 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing); 4317 if (existing != null) { 4318 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= " 4319 + existing.paused);; 4320 target.startsNotResumed = existing.paused; 4321 target.overrideConfig = existing.overrideConfig; 4322 } 4323 target.onlyLocalRequest = true; 4324 } 4325 mRelaunchingActivities.add(target); 4326 sendMessage(H.RELAUNCH_ACTIVITY, target); 4327 } 4328 4329 if (fromServer) { 4330 target.startsNotResumed = notResumed; 4331 target.onlyLocalRequest = false; 4332 } 4333 if (config != null) { 4334 target.createdConfig = config; 4335 } 4336 if (overrideConfig != null) { 4337 target.overrideConfig = overrideConfig; 4338 } 4339 target.pendingConfigChanges |= configChanges; 4340 target.relaunchSeq = getLifecycleSeq(); 4341 } 4342 if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this + ", target " 4343 + target + " operation received seq: " + target.relaunchSeq); 4344 } 4345 4346 private void handleRelaunchActivity(ActivityClientRecord tmp) { 4347 // If we are getting ready to gc after going to the background, well 4348 // we are back active so skip it. 4349 unscheduleGcIdler(); 4350 mSomeActivitiesChanged = true; 4351 4352 Configuration changedConfig = null; 4353 int configChanges = 0; 4354 4355 // First: make sure we have the most recent configuration and most 4356 // recent version of the activity, or skip it if some previous call 4357 // had taken a more recent version. 4358 synchronized (mResourcesManager) { 4359 int N = mRelaunchingActivities.size(); 4360 IBinder token = tmp.token; 4361 tmp = null; 4362 for (int i=0; i<N; i++) { 4363 ActivityClientRecord r = mRelaunchingActivities.get(i); 4364 if (r.token == token) { 4365 tmp = r; 4366 configChanges |= tmp.pendingConfigChanges; 4367 mRelaunchingActivities.remove(i); 4368 i--; 4369 N--; 4370 } 4371 } 4372 4373 if (tmp == null) { 4374 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 4375 return; 4376 } 4377 4378 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4379 + tmp.token + " with configChanges=0x" 4380 + Integer.toHexString(configChanges)); 4381 4382 if (mPendingConfiguration != null) { 4383 changedConfig = mPendingConfiguration; 4384 mPendingConfiguration = null; 4385 } 4386 } 4387 4388 if (tmp.lastProcessedSeq > tmp.relaunchSeq) { 4389 Slog.wtf(TAG, "For some reason target: " + tmp + " has lower sequence: " 4390 + tmp.relaunchSeq + " than current sequence: " + tmp.lastProcessedSeq); 4391 } else { 4392 tmp.lastProcessedSeq = tmp.relaunchSeq; 4393 } 4394 if (tmp.createdConfig != null) { 4395 // If the activity manager is passing us its current config, 4396 // assume that is really what we want regardless of what we 4397 // may have pending. 4398 if (mConfiguration == null 4399 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 4400 && mConfiguration.diff(tmp.createdConfig) != 0)) { 4401 if (changedConfig == null 4402 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 4403 changedConfig = tmp.createdConfig; 4404 } 4405 } 4406 } 4407 4408 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4409 + tmp.token + ": changedConfig=" + changedConfig); 4410 4411 // If there was a pending configuration change, execute it first. 4412 if (changedConfig != null) { 4413 mCurDefaultDisplayDpi = changedConfig.densityDpi; 4414 updateDefaultDensity(); 4415 handleConfigurationChanged(changedConfig, null); 4416 } 4417 4418 ActivityClientRecord r = mActivities.get(tmp.token); 4419 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 4420 if (r == null) { 4421 if (!tmp.onlyLocalRequest) { 4422 try { 4423 ActivityManagerNative.getDefault().activityRelaunched(tmp.token); 4424 } catch (RemoteException e) { 4425 throw e.rethrowFromSystemServer(); 4426 } 4427 } 4428 return; 4429 } 4430 4431 r.activity.mConfigChangeFlags |= configChanges; 4432 r.onlyLocalRequest = tmp.onlyLocalRequest; 4433 r.mPreserveWindow = tmp.mPreserveWindow; 4434 r.lastProcessedSeq = tmp.lastProcessedSeq; 4435 r.relaunchSeq = tmp.relaunchSeq; 4436 Intent currentIntent = r.activity.mIntent; 4437 4438 r.activity.mChangingConfigurations = true; 4439 4440 // If we are preserving the main window across relaunches we would also like to preserve 4441 // the children. However the client side view system does not support preserving 4442 // the child views so we notify the window manager to expect these windows to 4443 // be replaced and defer requests to destroy or hide them. This way we can achieve 4444 // visual continuity. It's important that we do this here prior to pause and destroy 4445 // as that is when we may hide or remove the child views. 4446 // 4447 // There is another scenario, if we have decided locally to relaunch the app from a 4448 // call to recreate, then none of the windows will be prepared for replacement or 4449 // preserved by the server, so we want to notify it that we are preparing to replace 4450 // everything 4451 try { 4452 if (r.mPreserveWindow || r.onlyLocalRequest) { 4453 WindowManagerGlobal.getWindowSession().prepareToReplaceWindows( 4454 r.token, !r.onlyLocalRequest); 4455 } 4456 } catch (RemoteException e) { 4457 throw e.rethrowFromSystemServer(); 4458 } 4459 4460 // Need to ensure state is saved. 4461 if (!r.paused) { 4462 performPauseActivity(r.token, false, r.isPreHoneycomb(), "handleRelaunchActivity"); 4463 } 4464 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 4465 callCallActivityOnSaveInstanceState(r); 4466 } 4467 4468 handleDestroyActivity(r.token, false, configChanges, true); 4469 4470 r.activity = null; 4471 r.window = null; 4472 r.hideForNow = false; 4473 r.nextIdle = null; 4474 // Merge any pending results and pending intents; don't just replace them 4475 if (tmp.pendingResults != null) { 4476 if (r.pendingResults == null) { 4477 r.pendingResults = tmp.pendingResults; 4478 } else { 4479 r.pendingResults.addAll(tmp.pendingResults); 4480 } 4481 } 4482 if (tmp.pendingIntents != null) { 4483 if (r.pendingIntents == null) { 4484 r.pendingIntents = tmp.pendingIntents; 4485 } else { 4486 r.pendingIntents.addAll(tmp.pendingIntents); 4487 } 4488 } 4489 r.startsNotResumed = tmp.startsNotResumed; 4490 r.overrideConfig = tmp.overrideConfig; 4491 4492 handleLaunchActivity(r, currentIntent, "handleRelaunchActivity"); 4493 4494 if (!tmp.onlyLocalRequest) { 4495 try { 4496 ActivityManagerNative.getDefault().activityRelaunched(r.token); 4497 if (r.window != null) { 4498 r.window.reportActivityRelaunched(); 4499 } 4500 } catch (RemoteException e) { 4501 throw e.rethrowFromSystemServer(); 4502 } 4503 } 4504 } 4505 4506 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) { 4507 r.state = new Bundle(); 4508 r.state.setAllowFds(false); 4509 if (r.isPersistable()) { 4510 r.persistentState = new PersistableBundle(); 4511 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, 4512 r.persistentState); 4513 } else { 4514 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 4515 } 4516 } 4517 4518 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 4519 boolean allActivities, Configuration newConfig) { 4520 ArrayList<ComponentCallbacks2> callbacks 4521 = new ArrayList<ComponentCallbacks2>(); 4522 4523 synchronized (mResourcesManager) { 4524 final int NAPP = mAllApplications.size(); 4525 for (int i=0; i<NAPP; i++) { 4526 callbacks.add(mAllApplications.get(i)); 4527 } 4528 final int NACT = mActivities.size(); 4529 for (int i=0; i<NACT; i++) { 4530 ActivityClientRecord ar = mActivities.valueAt(i); 4531 Activity a = ar.activity; 4532 if (a != null) { 4533 Configuration thisConfig = applyConfigCompatMainThread( 4534 mCurDefaultDisplayDpi, newConfig, 4535 ar.packageInfo.getCompatibilityInfo()); 4536 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 4537 // If the activity is currently resumed, its configuration 4538 // needs to change right now. 4539 callbacks.add(a); 4540 } else if (thisConfig != null) { 4541 // Otherwise, we will tell it about the change 4542 // the next time it is resumed or shown. Note that 4543 // the activity manager may, before then, decide the 4544 // activity needs to be destroyed to handle its new 4545 // configuration. 4546 if (DEBUG_CONFIGURATION) { 4547 Slog.v(TAG, "Setting activity " 4548 + ar.activityInfo.name + " newConfig=" + thisConfig); 4549 } 4550 ar.newConfig = thisConfig; 4551 } 4552 } 4553 } 4554 final int NSVC = mServices.size(); 4555 for (int i=0; i<NSVC; i++) { 4556 callbacks.add(mServices.valueAt(i)); 4557 } 4558 } 4559 synchronized (mProviderMap) { 4560 final int NPRV = mLocalProviders.size(); 4561 for (int i=0; i<NPRV; i++) { 4562 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 4563 } 4564 } 4565 4566 return callbacks; 4567 } 4568 4569 /** 4570 * Updates the configuration for an Activity. The ActivityClientRecord's 4571 * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for 4572 * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering 4573 * the updated Configuration. 4574 * @param r ActivityClientRecord representing the Activity. 4575 * @param newBaseConfig The new configuration to use. This may be augmented with 4576 * {@link ActivityClientRecord#overrideConfig}. 4577 * @param reportToActivity true if the change should be reported to the Activity's callback. 4578 */ 4579 private void performConfigurationChangedForActivity(ActivityClientRecord r, 4580 Configuration newBaseConfig, 4581 boolean reportToActivity) { 4582 r.tmpConfig.setTo(newBaseConfig); 4583 if (r.overrideConfig != null) { 4584 r.tmpConfig.updateFrom(r.overrideConfig); 4585 } 4586 performConfigurationChanged(r.activity, r.token, r.tmpConfig, r.overrideConfig, 4587 reportToActivity); 4588 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 4589 } 4590 4591 /** 4592 * Decides whether to update an Activity's configuration and whether to tell the 4593 * Activity/Component about it. 4594 * @param cb The component callback to notify of configuration change. 4595 * @param activityToken The Activity binder token for which this configuration change happened. 4596 * If the change is global, this is null. 4597 * @param newConfig The new configuration. 4598 * @param overrideConfig The override config that differentiates the Activity's configuration 4599 * from the base global configuration. 4600 * @param reportToActivity Notify the Activity of the change. 4601 */ 4602 private void performConfigurationChanged(ComponentCallbacks2 cb, 4603 IBinder activityToken, 4604 Configuration newConfig, 4605 Configuration overrideConfig, 4606 boolean reportToActivity) { 4607 // Only for Activity objects, check that they actually call up to their 4608 // superclass implementation. ComponentCallbacks2 is an interface, so 4609 // we check the runtime type and act accordingly. 4610 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 4611 if (activity != null) { 4612 activity.mCalled = false; 4613 } 4614 4615 boolean shouldChangeConfig = false; 4616 if ((activity == null) || (activity.mCurrentConfig == null)) { 4617 shouldChangeConfig = true; 4618 } else { 4619 4620 // If the new config is the same as the config this Activity 4621 // is already running with then don't bother calling 4622 // onConfigurationChanged 4623 int diff = activity.mCurrentConfig.diff(newConfig); 4624 if (diff != 0) { 4625 shouldChangeConfig = true; 4626 } 4627 } 4628 4629 if (DEBUG_CONFIGURATION) { 4630 Slog.v(TAG, "Config callback " + cb + ": shouldChangeConfig=" + shouldChangeConfig); 4631 } 4632 4633 if (shouldChangeConfig) { 4634 if (activityToken != null) { 4635 // We only update an Activity's configuration if this is not a global 4636 // configuration change. This must also be done before the callback, 4637 // or else we violate the contract that the new resources are available 4638 // in {@link ComponentCallbacks2#onConfigurationChanged(Configuration)}. 4639 mResourcesManager.updateResourcesForActivity(activityToken, overrideConfig); 4640 } 4641 4642 if (reportToActivity) { 4643 Configuration configToReport = newConfig; 4644 4645 if (cb instanceof ContextThemeWrapper) { 4646 // ContextThemeWrappers may override the configuration for that context. 4647 // We must check and apply any overrides defined. 4648 ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb; 4649 final Configuration localOverrideConfig = 4650 contextThemeWrapper.getOverrideConfiguration(); 4651 if (localOverrideConfig != null) { 4652 configToReport = new Configuration(newConfig); 4653 configToReport.updateFrom(localOverrideConfig); 4654 } 4655 } 4656 4657 cb.onConfigurationChanged(configToReport); 4658 } 4659 4660 if (activity != null) { 4661 if (reportToActivity && !activity.mCalled) { 4662 throw new SuperNotCalledException( 4663 "Activity " + activity.getLocalClassName() + 4664 " did not call through to super.onConfigurationChanged()"); 4665 } 4666 activity.mConfigChangeFlags = 0; 4667 activity.mCurrentConfig = new Configuration(newConfig); 4668 } 4669 } 4670 } 4671 4672 public final void applyConfigurationToResources(Configuration config) { 4673 synchronized (mResourcesManager) { 4674 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 4675 } 4676 } 4677 4678 final Configuration applyCompatConfiguration(int displayDensity) { 4679 Configuration config = mConfiguration; 4680 if (mCompatConfiguration == null) { 4681 mCompatConfiguration = new Configuration(); 4682 } 4683 mCompatConfiguration.setTo(mConfiguration); 4684 if (mResourcesManager.applyCompatConfigurationLocked(displayDensity, 4685 mCompatConfiguration)) { 4686 config = mCompatConfiguration; 4687 } 4688 return config; 4689 } 4690 4691 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 4692 4693 int configDiff = 0; 4694 4695 synchronized (mResourcesManager) { 4696 if (mPendingConfiguration != null) { 4697 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 4698 config = mPendingConfiguration; 4699 mCurDefaultDisplayDpi = config.densityDpi; 4700 updateDefaultDensity(); 4701 } 4702 mPendingConfiguration = null; 4703 } 4704 4705 if (config == null) { 4706 return; 4707 } 4708 4709 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 4710 + config); 4711 4712 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 4713 4714 if (mConfiguration == null) { 4715 mConfiguration = new Configuration(); 4716 } 4717 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 4718 return; 4719 } 4720 4721 configDiff = mConfiguration.updateFrom(config); 4722 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 4723 4724 final Theme systemTheme = getSystemContext().getTheme(); 4725 if ((systemTheme.getChangingConfigurations() & configDiff) != 0) { 4726 systemTheme.rebase(); 4727 } 4728 } 4729 4730 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 4731 4732 freeTextLayoutCachesIfNeeded(configDiff); 4733 4734 if (callbacks != null) { 4735 final int N = callbacks.size(); 4736 for (int i=0; i<N; i++) { 4737 ComponentCallbacks2 cb = callbacks.get(i); 4738 if (cb instanceof Activity) { 4739 // If callback is an Activity - call corresponding method to consider override 4740 // config and avoid onConfigurationChanged if it hasn't changed. 4741 Activity a = (Activity) cb; 4742 performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()), 4743 config, REPORT_TO_ACTIVITY); 4744 } else { 4745 performConfigurationChanged(cb, null, config, null, REPORT_TO_ACTIVITY); 4746 } 4747 } 4748 } 4749 } 4750 4751 static void freeTextLayoutCachesIfNeeded(int configDiff) { 4752 if (configDiff != 0) { 4753 // Ask text layout engine to free its caches if there is a locale change 4754 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 4755 if (hasLocaleConfigChange) { 4756 Canvas.freeTextLayoutCaches(); 4757 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 4758 } 4759 } 4760 } 4761 4762 final void handleActivityConfigurationChanged(ActivityConfigChangeData data, 4763 boolean reportToActivity) { 4764 ActivityClientRecord r = mActivities.get(data.activityToken); 4765 if (r == null || r.activity == null) { 4766 return; 4767 } 4768 4769 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 4770 + r.activityInfo.name + ", with callback=" + reportToActivity); 4771 4772 r.overrideConfig = data.overrideConfig; 4773 performConfigurationChangedForActivity(r, mCompatConfiguration, reportToActivity); 4774 mSomeActivitiesChanged = true; 4775 } 4776 4777 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 4778 if (start) { 4779 try { 4780 switch (profileType) { 4781 default: 4782 mProfiler.setProfiler(profilerInfo); 4783 mProfiler.startProfiling(); 4784 break; 4785 } 4786 } catch (RuntimeException e) { 4787 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile 4788 + " -- can the process access this path?"); 4789 } finally { 4790 try { 4791 profilerInfo.profileFd.close(); 4792 } catch (IOException e) { 4793 Slog.w(TAG, "Failure closing profile fd", e); 4794 } 4795 } 4796 } else { 4797 switch (profileType) { 4798 default: 4799 mProfiler.stopProfiling(); 4800 break; 4801 } 4802 } 4803 } 4804 4805 /** 4806 * Public entrypoint to stop profiling. This is required to end profiling when the app crashes, 4807 * so that profiler data won't be lost. 4808 * 4809 * @hide 4810 */ 4811 public void stopProfiling() { 4812 mProfiler.stopProfiling(); 4813 } 4814 4815 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 4816 if (managed) { 4817 try { 4818 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 4819 } catch (IOException e) { 4820 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 4821 + " -- can the process access this path?"); 4822 } finally { 4823 try { 4824 dhd.fd.close(); 4825 } catch (IOException e) { 4826 Slog.w(TAG, "Failure closing profile fd", e); 4827 } 4828 } 4829 } else { 4830 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 4831 } 4832 try { 4833 ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path); 4834 } catch (RemoteException e) { 4835 throw e.rethrowFromSystemServer(); 4836 } 4837 } 4838 4839 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 4840 boolean hasPkgInfo = false; 4841 switch (cmd) { 4842 case IApplicationThread.PACKAGE_REMOVED: 4843 case IApplicationThread.PACKAGE_REMOVED_DONT_KILL: 4844 { 4845 final boolean killApp = cmd == IApplicationThread.PACKAGE_REMOVED; 4846 if (packages == null) { 4847 break; 4848 } 4849 synchronized (mResourcesManager) { 4850 for (int i = packages.length - 1; i >= 0; i--) { 4851 if (!hasPkgInfo) { 4852 WeakReference<LoadedApk> ref = mPackages.get(packages[i]); 4853 if (ref != null && ref.get() != null) { 4854 hasPkgInfo = true; 4855 } else { 4856 ref = mResourcePackages.get(packages[i]); 4857 if (ref != null && ref.get() != null) { 4858 hasPkgInfo = true; 4859 } 4860 } 4861 } 4862 if (killApp) { 4863 mPackages.remove(packages[i]); 4864 mResourcePackages.remove(packages[i]); 4865 } 4866 } 4867 } 4868 break; 4869 } 4870 case IApplicationThread.PACKAGE_REPLACED: 4871 { 4872 if (packages == null) { 4873 break; 4874 } 4875 synchronized (mResourcesManager) { 4876 for (int i = packages.length - 1; i >= 0; i--) { 4877 WeakReference<LoadedApk> ref = mPackages.get(packages[i]); 4878 LoadedApk pkgInfo = ref != null ? ref.get() : null; 4879 if (pkgInfo != null) { 4880 hasPkgInfo = true; 4881 } else { 4882 ref = mResourcePackages.get(packages[i]); 4883 pkgInfo = ref != null ? ref.get() : null; 4884 if (pkgInfo != null) { 4885 hasPkgInfo = true; 4886 } 4887 } 4888 // If the package is being replaced, yet it still has a valid 4889 // LoadedApk object, the package was updated with _DONT_KILL. 4890 // Adjust it's internal references to the application info and 4891 // resources. 4892 if (pkgInfo != null) { 4893 try { 4894 final String packageName = packages[i]; 4895 final ApplicationInfo aInfo = 4896 sPackageManager.getApplicationInfo( 4897 packageName, 4898 0 /*flags*/, 4899 UserHandle.myUserId()); 4900 4901 if (mActivities.size() > 0) { 4902 for (ActivityClientRecord ar : mActivities.values()) { 4903 if (ar.activityInfo.applicationInfo.packageName 4904 .equals(packageName)) { 4905 ar.activityInfo.applicationInfo = aInfo; 4906 ar.packageInfo = pkgInfo; 4907 } 4908 } 4909 } 4910 final List<String> oldPaths = 4911 sPackageManager.getPreviousCodePaths(packageName); 4912 pkgInfo.updateApplicationInfo(aInfo, oldPaths); 4913 } catch (RemoteException e) { 4914 } 4915 } 4916 } 4917 } 4918 break; 4919 } 4920 } 4921 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo); 4922 } 4923 4924 final void handleLowMemory() { 4925 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4926 4927 final int N = callbacks.size(); 4928 for (int i=0; i<N; i++) { 4929 callbacks.get(i).onLowMemory(); 4930 } 4931 4932 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4933 if (Process.myUid() != Process.SYSTEM_UID) { 4934 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4935 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4936 } 4937 4938 // Ask graphics to free up as much as possible (font/image caches) 4939 Canvas.freeCaches(); 4940 4941 // Ask text layout engine to free also as much as possible 4942 Canvas.freeTextLayoutCaches(); 4943 4944 BinderInternal.forceGc("mem"); 4945 } 4946 4947 final void handleTrimMemory(int level) { 4948 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4949 4950 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4951 4952 final int N = callbacks.size(); 4953 for (int i = 0; i < N; i++) { 4954 callbacks.get(i).onTrimMemory(level); 4955 } 4956 4957 WindowManagerGlobal.getInstance().trimMemory(level); 4958 } 4959 4960 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4961 if (Process.isIsolated()) { 4962 // Isolated processes aren't going to do UI. 4963 return; 4964 } 4965 try { 4966 int uid = Process.myUid(); 4967 String[] packages = getPackageManager().getPackagesForUid(uid); 4968 4969 // If there are several packages in this application we won't 4970 // initialize the graphics disk caches 4971 if (packages != null && packages.length == 1) { 4972 ThreadedRenderer.setupDiskCache(cacheDir); 4973 RenderScriptCacheDir.setupDiskCache(cacheDir); 4974 } 4975 } catch (RemoteException e) { 4976 throw e.rethrowFromSystemServer(); 4977 } 4978 } 4979 4980 private void updateDefaultDensity() { 4981 final int densityDpi = mCurDefaultDisplayDpi; 4982 if (!mDensityCompatMode 4983 && densityDpi != Configuration.DENSITY_DPI_UNDEFINED 4984 && densityDpi != DisplayMetrics.DENSITY_DEVICE) { 4985 DisplayMetrics.DENSITY_DEVICE = densityDpi; 4986 Bitmap.setDefaultDensity(densityDpi); 4987 } 4988 } 4989 4990 private void handleBindApplication(AppBindData data) { 4991 // Register the UI Thread as a sensitive thread to the runtime. 4992 VMRuntime.registerSensitiveThread(); 4993 if (data.trackAllocation) { 4994 DdmVmInternal.enableRecentAllocations(true); 4995 } 4996 4997 // Note when this process has started. 4998 Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); 4999 5000 mBoundApplication = data; 5001 mConfiguration = new Configuration(data.config); 5002 mCompatConfiguration = new Configuration(data.config); 5003 5004 mProfiler = new Profiler(); 5005 if (data.initProfilerInfo != null) { 5006 mProfiler.profileFile = data.initProfilerInfo.profileFile; 5007 mProfiler.profileFd = data.initProfilerInfo.profileFd; 5008 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; 5009 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; 5010 } 5011 5012 // send up app name; do this *before* waiting for debugger 5013 Process.setArgV0(data.processName); 5014 android.ddm.DdmHandleAppName.setAppName(data.processName, 5015 UserHandle.myUserId()); 5016 5017 if (data.persistent) { 5018 // Persistent processes on low-memory devices do not get to 5019 // use hardware accelerated drawing, since this can add too much 5020 // overhead to the process. 5021 if (!ActivityManager.isHighEndGfx()) { 5022 ThreadedRenderer.disable(false); 5023 } 5024 } 5025 5026 if (mProfiler.profileFd != null) { 5027 mProfiler.startProfiling(); 5028 } 5029 5030 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 5031 // implementation to use the pool executor. Normally, we use the 5032 // serialized executor as the default. This has to happen in the 5033 // main thread so the main looper is set right. 5034 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 5035 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 5036 } 5037 5038 Message.updateCheckRecycle(data.appInfo.targetSdkVersion); 5039 5040 /* 5041 * Before spawning a new process, reset the time zone to be the system time zone. 5042 * This needs to be done because the system time zone could have changed after the 5043 * the spawning of this process. Without doing this this process would have the incorrect 5044 * system time zone. 5045 */ 5046 TimeZone.setDefault(null); 5047 5048 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 5049 5050 /** 5051 * Switch this process to density compatibility mode if needed. 5052 */ 5053 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 5054 == 0) { 5055 mDensityCompatMode = true; 5056 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 5057 } 5058 updateDefaultDensity(); 5059 5060 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24)); 5061 DateFormat.set24HourTimePref(is24Hr); 5062 5063 View.mDebugViewAttributes = 5064 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 5065 5066 /** 5067 * For system applications on userdebug/eng builds, log stack 5068 * traces of disk and network access to dropbox for analysis. 5069 */ 5070 if ((data.appInfo.flags & 5071 (ApplicationInfo.FLAG_SYSTEM | 5072 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 5073 StrictMode.conditionallyEnableDebugLogging(); 5074 } 5075 5076 /** 5077 * For apps targetting Honeycomb or later, we don't allow network usage 5078 * on the main event loop / UI thread. This is what ultimately throws 5079 * {@link NetworkOnMainThreadException}. 5080 */ 5081 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) { 5082 StrictMode.enableDeathOnNetwork(); 5083 } 5084 5085 /** 5086 * For apps targetting N or later, we don't allow file:// Uri exposure. 5087 * This is what ultimately throws {@link FileUriExposedException}. 5088 */ 5089 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 5090 StrictMode.enableDeathOnFileUriExposure(); 5091 } 5092 5093 NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted( 5094 (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0); 5095 5096 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 5097 // XXX should have option to change the port. 5098 Debug.changeDebugPort(8100); 5099 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 5100 Slog.w(TAG, "Application " + data.info.getPackageName() 5101 + " is waiting for the debugger on port 8100..."); 5102 5103 IActivityManager mgr = ActivityManagerNative.getDefault(); 5104 try { 5105 mgr.showWaitingForDebugger(mAppThread, true); 5106 } catch (RemoteException ex) { 5107 throw ex.rethrowFromSystemServer(); 5108 } 5109 5110 Debug.waitForDebugger(); 5111 5112 try { 5113 mgr.showWaitingForDebugger(mAppThread, false); 5114 } catch (RemoteException ex) { 5115 throw ex.rethrowFromSystemServer(); 5116 } 5117 5118 } else { 5119 Slog.w(TAG, "Application " + data.info.getPackageName() 5120 + " can be debugged on port 8100..."); 5121 } 5122 } 5123 5124 // Allow application-generated systrace messages if we're debuggable. 5125 boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 5126 Trace.setAppTracingAllowed(isAppDebuggable); 5127 if (isAppDebuggable && data.enableBinderTracking) { 5128 Binder.enableTracing(); 5129 } 5130 5131 /** 5132 * Initialize the default http proxy in this process for the reasons we set the time zone. 5133 */ 5134 final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 5135 if (b != null) { 5136 // In pre-boot mode (doing initial launch to collect password), not 5137 // all system is up. This includes the connectivity service, so don't 5138 // crash if we can't get it. 5139 final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 5140 try { 5141 final ProxyInfo proxyInfo = service.getProxyForNetwork(null); 5142 Proxy.setHttpProxySystemProperty(proxyInfo); 5143 } catch (RemoteException e) { 5144 throw e.rethrowFromSystemServer(); 5145 } 5146 } 5147 5148 // Instrumentation info affects the class loader, so load it before 5149 // setting up the app context. 5150 final InstrumentationInfo ii; 5151 if (data.instrumentationName != null) { 5152 try { 5153 ii = new ApplicationPackageManager(null, getPackageManager()) 5154 .getInstrumentationInfo(data.instrumentationName, 0); 5155 } catch (PackageManager.NameNotFoundException e) { 5156 throw new RuntimeException( 5157 "Unable to find instrumentation info for: " + data.instrumentationName); 5158 } 5159 5160 mInstrumentationPackageName = ii.packageName; 5161 mInstrumentationAppDir = ii.sourceDir; 5162 mInstrumentationSplitAppDirs = ii.splitSourceDirs; 5163 mInstrumentationLibDir = ii.nativeLibraryDir; 5164 mInstrumentedAppDir = data.info.getAppDir(); 5165 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); 5166 mInstrumentedLibDir = data.info.getLibDir(); 5167 } else { 5168 ii = null; 5169 } 5170 5171 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 5172 synchronized (mResourcesManager) { 5173 /* 5174 * Initialize the default locales in this process for the reasons we set the time zone. 5175 * 5176 * We do this through ResourcesManager, since we need to do locale negotiation. 5177 */ 5178 mResourcesManager.setDefaultLocalesLocked(data.config.getLocales()); 5179 5180 /* 5181 * Update the system configuration since its preloaded and might not 5182 * reflect configuration changes. The configuration object passed 5183 * in AppBindData can be safely assumed to be up to date 5184 */ 5185 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 5186 mCurDefaultDisplayDpi = data.config.densityDpi; 5187 5188 // This calls mResourcesManager so keep it within the synchronized block. 5189 applyCompatConfiguration(mCurDefaultDisplayDpi); 5190 } 5191 5192 if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) { 5193 // This cache location probably points at credential-encrypted 5194 // storage which may not be accessible yet; assign it anyway instead 5195 // of pointing at device-encrypted storage. 5196 final File cacheDir = appContext.getCacheDir(); 5197 if (cacheDir != null) { 5198 // Provide a usable directory for temporary files 5199 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 5200 } else { 5201 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property " 5202 + "due to missing cache directory"); 5203 } 5204 5205 // Setup a location to store generated/compiled graphics code. 5206 final Context deviceContext = appContext.createDeviceProtectedStorageContext(); 5207 final File codeCacheDir = deviceContext.getCodeCacheDir(); 5208 if (codeCacheDir != null) { 5209 setupGraphicsSupport(data.info, codeCacheDir); 5210 } else { 5211 Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory"); 5212 } 5213 5214 // Add the lib dir path to hardware renderer so that vulkan layers 5215 // can be searched for within that directory. 5216 ThreadedRenderer.setLibDir(data.info.getLibDir()); 5217 } 5218 5219 // Install the Network Security Config Provider. This must happen before the application 5220 // code is loaded to prevent issues with instances of TLS objects being created before 5221 // the provider is installed. 5222 NetworkSecurityConfigProvider.install(appContext); 5223 5224 // Continue loading instrumentation. 5225 if (ii != null) { 5226 final ApplicationInfo instrApp = new ApplicationInfo(); 5227 ii.copyTo(instrApp); 5228 instrApp.initForUser(UserHandle.myUserId()); 5229 final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 5230 appContext.getClassLoader(), false, true, false); 5231 final ContextImpl instrContext = ContextImpl.createAppContext(this, pi); 5232 5233 try { 5234 final ClassLoader cl = instrContext.getClassLoader(); 5235 mInstrumentation = (Instrumentation) 5236 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 5237 } catch (Exception e) { 5238 throw new RuntimeException( 5239 "Unable to instantiate instrumentation " 5240 + data.instrumentationName + ": " + e.toString(), e); 5241 } 5242 5243 final ComponentName component = new ComponentName(ii.packageName, ii.name); 5244 mInstrumentation.init(this, instrContext, appContext, component, 5245 data.instrumentationWatcher, data.instrumentationUiAutomationConnection); 5246 5247 if (mProfiler.profileFile != null && !ii.handleProfiling 5248 && mProfiler.profileFd == null) { 5249 mProfiler.handlingProfiling = true; 5250 final File file = new File(mProfiler.profileFile); 5251 file.getParentFile().mkdirs(); 5252 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 5253 } 5254 } else { 5255 mInstrumentation = new Instrumentation(); 5256 } 5257 5258 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 5259 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 5260 } else { 5261 // Small heap, clamp to the current growth limit and let the heap release 5262 // pages after the growth limit to the non growth limit capacity. b/18387825 5263 dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); 5264 } 5265 5266 // Allow disk access during application and provider setup. This could 5267 // block processing ordered broadcasts, but later processing would 5268 // probably end up doing the same disk access. 5269 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 5270 try { 5271 // If the app is being launched for full backup or restore, bring it up in 5272 // a restricted environment with the base application class. 5273 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 5274 mInitialApplication = app; 5275 5276 // don't bring up providers in restricted mode; they may depend on the 5277 // app's custom Application class 5278 if (!data.restrictedBackupMode) { 5279 if (!ArrayUtils.isEmpty(data.providers)) { 5280 installContentProviders(app, data.providers); 5281 // For process that contains content providers, we want to 5282 // ensure that the JIT is enabled "at some point". 5283 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 5284 } 5285 } 5286 5287 // Do this after providers, since instrumentation tests generally start their 5288 // test thread at this point, and we don't want that racing. 5289 try { 5290 mInstrumentation.onCreate(data.instrumentationArgs); 5291 } 5292 catch (Exception e) { 5293 throw new RuntimeException( 5294 "Exception thrown in onCreate() of " 5295 + data.instrumentationName + ": " + e.toString(), e); 5296 } 5297 5298 try { 5299 mInstrumentation.callApplicationOnCreate(app); 5300 } catch (Exception e) { 5301 if (!mInstrumentation.onException(app, e)) { 5302 throw new RuntimeException( 5303 "Unable to create application " + app.getClass().getName() 5304 + ": " + e.toString(), e); 5305 } 5306 } 5307 } finally { 5308 StrictMode.setThreadPolicy(savedPolicy); 5309 } 5310 } 5311 5312 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 5313 IActivityManager am = ActivityManagerNative.getDefault(); 5314 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 5315 && mProfiler.profileFd == null) { 5316 Debug.stopMethodTracing(); 5317 } 5318 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 5319 // + ", app thr: " + mAppThread); 5320 try { 5321 am.finishInstrumentation(mAppThread, resultCode, results); 5322 } catch (RemoteException ex) { 5323 throw ex.rethrowFromSystemServer(); 5324 } 5325 } 5326 5327 private void installContentProviders( 5328 Context context, List<ProviderInfo> providers) { 5329 final ArrayList<IActivityManager.ContentProviderHolder> results = 5330 new ArrayList<IActivityManager.ContentProviderHolder>(); 5331 5332 for (ProviderInfo cpi : providers) { 5333 if (DEBUG_PROVIDER) { 5334 StringBuilder buf = new StringBuilder(128); 5335 buf.append("Pub "); 5336 buf.append(cpi.authority); 5337 buf.append(": "); 5338 buf.append(cpi.name); 5339 Log.i(TAG, buf.toString()); 5340 } 5341 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 5342 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 5343 if (cph != null) { 5344 cph.noReleaseNeeded = true; 5345 results.add(cph); 5346 } 5347 } 5348 5349 try { 5350 ActivityManagerNative.getDefault().publishContentProviders( 5351 getApplicationThread(), results); 5352 } catch (RemoteException ex) { 5353 throw ex.rethrowFromSystemServer(); 5354 } 5355 } 5356 5357 public final IContentProvider acquireProvider( 5358 Context c, String auth, int userId, boolean stable) { 5359 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 5360 if (provider != null) { 5361 return provider; 5362 } 5363 5364 // There is a possible race here. Another thread may try to acquire 5365 // the same provider at the same time. When this happens, we want to ensure 5366 // that the first one wins. 5367 // Note that we cannot hold the lock while acquiring and installing the 5368 // provider since it might take a long time to run and it could also potentially 5369 // be re-entrant in the case where the provider is in the same process. 5370 IActivityManager.ContentProviderHolder holder = null; 5371 try { 5372 holder = ActivityManagerNative.getDefault().getContentProvider( 5373 getApplicationThread(), auth, userId, stable); 5374 } catch (RemoteException ex) { 5375 throw ex.rethrowFromSystemServer(); 5376 } 5377 if (holder == null) { 5378 Slog.e(TAG, "Failed to find provider info for " + auth); 5379 return null; 5380 } 5381 5382 // Install provider will increment the reference count for us, and break 5383 // any ties in the race. 5384 holder = installProvider(c, holder, holder.info, 5385 true /*noisy*/, holder.noReleaseNeeded, stable); 5386 return holder.provider; 5387 } 5388 5389 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 5390 if (stable) { 5391 prc.stableCount += 1; 5392 if (prc.stableCount == 1) { 5393 // We are acquiring a new stable reference on the provider. 5394 int unstableDelta; 5395 if (prc.removePending) { 5396 // We have a pending remove operation, which is holding the 5397 // last unstable reference. At this point we are converting 5398 // that unstable reference to our new stable reference. 5399 unstableDelta = -1; 5400 // Cancel the removal of the provider. 5401 if (DEBUG_PROVIDER) { 5402 Slog.v(TAG, "incProviderRef: stable " 5403 + "snatched provider from the jaws of death"); 5404 } 5405 prc.removePending = false; 5406 // There is a race! It fails to remove the message, which 5407 // will be handled in completeRemoveProvider(). 5408 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5409 } else { 5410 unstableDelta = 0; 5411 } 5412 try { 5413 if (DEBUG_PROVIDER) { 5414 Slog.v(TAG, "incProviderRef Now stable - " 5415 + prc.holder.info.name + ": unstableDelta=" 5416 + unstableDelta); 5417 } 5418 ActivityManagerNative.getDefault().refContentProvider( 5419 prc.holder.connection, 1, unstableDelta); 5420 } catch (RemoteException e) { 5421 //do nothing content provider object is dead any way 5422 } 5423 } 5424 } else { 5425 prc.unstableCount += 1; 5426 if (prc.unstableCount == 1) { 5427 // We are acquiring a new unstable reference on the provider. 5428 if (prc.removePending) { 5429 // Oh look, we actually have a remove pending for the 5430 // provider, which is still holding the last unstable 5431 // reference. We just need to cancel that to take new 5432 // ownership of the reference. 5433 if (DEBUG_PROVIDER) { 5434 Slog.v(TAG, "incProviderRef: unstable " 5435 + "snatched provider from the jaws of death"); 5436 } 5437 prc.removePending = false; 5438 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5439 } else { 5440 // First unstable ref, increment our count in the 5441 // activity manager. 5442 try { 5443 if (DEBUG_PROVIDER) { 5444 Slog.v(TAG, "incProviderRef: Now unstable - " 5445 + prc.holder.info.name); 5446 } 5447 ActivityManagerNative.getDefault().refContentProvider( 5448 prc.holder.connection, 0, 1); 5449 } catch (RemoteException e) { 5450 //do nothing content provider object is dead any way 5451 } 5452 } 5453 } 5454 } 5455 } 5456 5457 public final IContentProvider acquireExistingProvider( 5458 Context c, String auth, int userId, boolean stable) { 5459 synchronized (mProviderMap) { 5460 final ProviderKey key = new ProviderKey(auth, userId); 5461 final ProviderClientRecord pr = mProviderMap.get(key); 5462 if (pr == null) { 5463 return null; 5464 } 5465 5466 IContentProvider provider = pr.mProvider; 5467 IBinder jBinder = provider.asBinder(); 5468 if (!jBinder.isBinderAlive()) { 5469 // The hosting process of the provider has died; we can't 5470 // use this one. 5471 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 5472 + ": existing object's process dead"); 5473 handleUnstableProviderDiedLocked(jBinder, true); 5474 return null; 5475 } 5476 5477 // Only increment the ref count if we have one. If we don't then the 5478 // provider is not reference counted and never needs to be released. 5479 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5480 if (prc != null) { 5481 incProviderRefLocked(prc, stable); 5482 } 5483 return provider; 5484 } 5485 } 5486 5487 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 5488 if (provider == null) { 5489 return false; 5490 } 5491 5492 IBinder jBinder = provider.asBinder(); 5493 synchronized (mProviderMap) { 5494 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5495 if (prc == null) { 5496 // The provider has no ref count, no release is needed. 5497 return false; 5498 } 5499 5500 boolean lastRef = false; 5501 if (stable) { 5502 if (prc.stableCount == 0) { 5503 if (DEBUG_PROVIDER) Slog.v(TAG, 5504 "releaseProvider: stable ref count already 0, how?"); 5505 return false; 5506 } 5507 prc.stableCount -= 1; 5508 if (prc.stableCount == 0) { 5509 // What we do at this point depends on whether there are 5510 // any unstable refs left: if there are, we just tell the 5511 // activity manager to decrement its stable count; if there 5512 // aren't, we need to enqueue this provider to be removed, 5513 // and convert to holding a single unstable ref while 5514 // doing so. 5515 lastRef = prc.unstableCount == 0; 5516 try { 5517 if (DEBUG_PROVIDER) { 5518 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 5519 + lastRef + " - " + prc.holder.info.name); 5520 } 5521 ActivityManagerNative.getDefault().refContentProvider( 5522 prc.holder.connection, -1, lastRef ? 1 : 0); 5523 } catch (RemoteException e) { 5524 //do nothing content provider object is dead any way 5525 } 5526 } 5527 } else { 5528 if (prc.unstableCount == 0) { 5529 if (DEBUG_PROVIDER) Slog.v(TAG, 5530 "releaseProvider: unstable ref count already 0, how?"); 5531 return false; 5532 } 5533 prc.unstableCount -= 1; 5534 if (prc.unstableCount == 0) { 5535 // If this is the last reference, we need to enqueue 5536 // this provider to be removed instead of telling the 5537 // activity manager to remove it at this point. 5538 lastRef = prc.stableCount == 0; 5539 if (!lastRef) { 5540 try { 5541 if (DEBUG_PROVIDER) { 5542 Slog.v(TAG, "releaseProvider: No longer unstable - " 5543 + prc.holder.info.name); 5544 } 5545 ActivityManagerNative.getDefault().refContentProvider( 5546 prc.holder.connection, 0, -1); 5547 } catch (RemoteException e) { 5548 //do nothing content provider object is dead any way 5549 } 5550 } 5551 } 5552 } 5553 5554 if (lastRef) { 5555 if (!prc.removePending) { 5556 // Schedule the actual remove asynchronously, since we don't know the context 5557 // this will be called in. 5558 // TODO: it would be nice to post a delayed message, so 5559 // if we come back and need the same provider quickly 5560 // we will still have it available. 5561 if (DEBUG_PROVIDER) { 5562 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 5563 + prc.holder.info.name); 5564 } 5565 prc.removePending = true; 5566 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 5567 mH.sendMessage(msg); 5568 } else { 5569 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 5570 } 5571 } 5572 return true; 5573 } 5574 } 5575 5576 final void completeRemoveProvider(ProviderRefCount prc) { 5577 synchronized (mProviderMap) { 5578 if (!prc.removePending) { 5579 // There was a race! Some other client managed to acquire 5580 // the provider before the removal was completed. 5581 // Abort the removal. We will do it later. 5582 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 5583 + "provider still in use"); 5584 return; 5585 } 5586 5587 // More complicated race!! Some client managed to acquire the 5588 // provider and release it before the removal was completed. 5589 // Continue the removal, and abort the next remove message. 5590 prc.removePending = false; 5591 5592 final IBinder jBinder = prc.holder.provider.asBinder(); 5593 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 5594 if (existingPrc == prc) { 5595 mProviderRefCountMap.remove(jBinder); 5596 } 5597 5598 for (int i=mProviderMap.size()-1; i>=0; i--) { 5599 ProviderClientRecord pr = mProviderMap.valueAt(i); 5600 IBinder myBinder = pr.mProvider.asBinder(); 5601 if (myBinder == jBinder) { 5602 mProviderMap.removeAt(i); 5603 } 5604 } 5605 } 5606 5607 try { 5608 if (DEBUG_PROVIDER) { 5609 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 5610 + "removeContentProvider(" + prc.holder.info.name + ")"); 5611 } 5612 ActivityManagerNative.getDefault().removeContentProvider( 5613 prc.holder.connection, false); 5614 } catch (RemoteException e) { 5615 //do nothing content provider object is dead any way 5616 } 5617 } 5618 5619 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 5620 synchronized (mProviderMap) { 5621 handleUnstableProviderDiedLocked(provider, fromClient); 5622 } 5623 } 5624 5625 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 5626 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5627 if (prc != null) { 5628 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 5629 + provider + " " + prc.holder.info.name); 5630 mProviderRefCountMap.remove(provider); 5631 for (int i=mProviderMap.size()-1; i>=0; i--) { 5632 ProviderClientRecord pr = mProviderMap.valueAt(i); 5633 if (pr != null && pr.mProvider.asBinder() == provider) { 5634 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 5635 mProviderMap.removeAt(i); 5636 } 5637 } 5638 5639 if (fromClient) { 5640 // We found out about this due to execution in our client 5641 // code. Tell the activity manager about it now, to ensure 5642 // that the next time we go to do anything with the provider 5643 // it knows it is dead (so we don't race with its death 5644 // notification). 5645 try { 5646 ActivityManagerNative.getDefault().unstableProviderDied( 5647 prc.holder.connection); 5648 } catch (RemoteException e) { 5649 //do nothing content provider object is dead any way 5650 } 5651 } 5652 } 5653 } 5654 5655 final void appNotRespondingViaProvider(IBinder provider) { 5656 synchronized (mProviderMap) { 5657 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5658 if (prc != null) { 5659 try { 5660 ActivityManagerNative.getDefault() 5661 .appNotRespondingViaProvider(prc.holder.connection); 5662 } catch (RemoteException e) { 5663 throw e.rethrowFromSystemServer(); 5664 } 5665 } 5666 } 5667 } 5668 5669 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 5670 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 5671 final String auths[] = holder.info.authority.split(";"); 5672 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 5673 5674 final ProviderClientRecord pcr = new ProviderClientRecord( 5675 auths, provider, localProvider, holder); 5676 for (String auth : auths) { 5677 final ProviderKey key = new ProviderKey(auth, userId); 5678 final ProviderClientRecord existing = mProviderMap.get(key); 5679 if (existing != null) { 5680 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 5681 + " already published as " + auth); 5682 } else { 5683 mProviderMap.put(key, pcr); 5684 } 5685 } 5686 return pcr; 5687 } 5688 5689 /** 5690 * Installs the provider. 5691 * 5692 * Providers that are local to the process or that come from the system server 5693 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 5694 * Other remote providers are reference counted. The initial reference count 5695 * for all reference counted providers is one. Providers that are not reference 5696 * counted do not have a reference count (at all). 5697 * 5698 * This method detects when a provider has already been installed. When this happens, 5699 * it increments the reference count of the existing provider (if appropriate) 5700 * and returns the existing provider. This can happen due to concurrent 5701 * attempts to acquire the same provider. 5702 */ 5703 private IActivityManager.ContentProviderHolder installProvider(Context context, 5704 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 5705 boolean noisy, boolean noReleaseNeeded, boolean stable) { 5706 ContentProvider localProvider = null; 5707 IContentProvider provider; 5708 if (holder == null || holder.provider == null) { 5709 if (DEBUG_PROVIDER || noisy) { 5710 Slog.d(TAG, "Loading provider " + info.authority + ": " 5711 + info.name); 5712 } 5713 Context c = null; 5714 ApplicationInfo ai = info.applicationInfo; 5715 if (context.getPackageName().equals(ai.packageName)) { 5716 c = context; 5717 } else if (mInitialApplication != null && 5718 mInitialApplication.getPackageName().equals(ai.packageName)) { 5719 c = mInitialApplication; 5720 } else { 5721 try { 5722 c = context.createPackageContext(ai.packageName, 5723 Context.CONTEXT_INCLUDE_CODE); 5724 } catch (PackageManager.NameNotFoundException e) { 5725 // Ignore 5726 } 5727 } 5728 if (c == null) { 5729 Slog.w(TAG, "Unable to get context for package " + 5730 ai.packageName + 5731 " while loading content provider " + 5732 info.name); 5733 return null; 5734 } 5735 try { 5736 final java.lang.ClassLoader cl = c.getClassLoader(); 5737 localProvider = (ContentProvider)cl. 5738 loadClass(info.name).newInstance(); 5739 provider = localProvider.getIContentProvider(); 5740 if (provider == null) { 5741 Slog.e(TAG, "Failed to instantiate class " + 5742 info.name + " from sourceDir " + 5743 info.applicationInfo.sourceDir); 5744 return null; 5745 } 5746 if (DEBUG_PROVIDER) Slog.v( 5747 TAG, "Instantiating local provider " + info.name); 5748 // XXX Need to create the correct context for this provider. 5749 localProvider.attachInfo(c, info); 5750 } catch (java.lang.Exception e) { 5751 if (!mInstrumentation.onException(null, e)) { 5752 throw new RuntimeException( 5753 "Unable to get provider " + info.name 5754 + ": " + e.toString(), e); 5755 } 5756 return null; 5757 } 5758 } else { 5759 provider = holder.provider; 5760 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 5761 + info.name); 5762 } 5763 5764 IActivityManager.ContentProviderHolder retHolder; 5765 5766 synchronized (mProviderMap) { 5767 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 5768 + " / " + info.name); 5769 IBinder jBinder = provider.asBinder(); 5770 if (localProvider != null) { 5771 ComponentName cname = new ComponentName(info.packageName, info.name); 5772 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 5773 if (pr != null) { 5774 if (DEBUG_PROVIDER) { 5775 Slog.v(TAG, "installProvider: lost the race, " 5776 + "using existing local provider"); 5777 } 5778 provider = pr.mProvider; 5779 } else { 5780 holder = new IActivityManager.ContentProviderHolder(info); 5781 holder.provider = provider; 5782 holder.noReleaseNeeded = true; 5783 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 5784 mLocalProviders.put(jBinder, pr); 5785 mLocalProvidersByName.put(cname, pr); 5786 } 5787 retHolder = pr.mHolder; 5788 } else { 5789 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5790 if (prc != null) { 5791 if (DEBUG_PROVIDER) { 5792 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 5793 } 5794 // We need to transfer our new reference to the existing 5795 // ref count, releasing the old one... but only if 5796 // release is needed (that is, it is not running in the 5797 // system process). 5798 if (!noReleaseNeeded) { 5799 incProviderRefLocked(prc, stable); 5800 try { 5801 ActivityManagerNative.getDefault().removeContentProvider( 5802 holder.connection, stable); 5803 } catch (RemoteException e) { 5804 //do nothing content provider object is dead any way 5805 } 5806 } 5807 } else { 5808 ProviderClientRecord client = installProviderAuthoritiesLocked( 5809 provider, localProvider, holder); 5810 if (noReleaseNeeded) { 5811 prc = new ProviderRefCount(holder, client, 1000, 1000); 5812 } else { 5813 prc = stable 5814 ? new ProviderRefCount(holder, client, 1, 0) 5815 : new ProviderRefCount(holder, client, 0, 1); 5816 } 5817 mProviderRefCountMap.put(jBinder, prc); 5818 } 5819 retHolder = prc.holder; 5820 } 5821 } 5822 5823 return retHolder; 5824 } 5825 5826 private void attach(boolean system) { 5827 sCurrentActivityThread = this; 5828 mSystemThread = system; 5829 if (!system) { 5830 ViewRootImpl.addFirstDrawHandler(new Runnable() { 5831 @Override 5832 public void run() { 5833 ensureJitEnabled(); 5834 } 5835 }); 5836 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 5837 UserHandle.myUserId()); 5838 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 5839 final IActivityManager mgr = ActivityManagerNative.getDefault(); 5840 try { 5841 mgr.attachApplication(mAppThread); 5842 } catch (RemoteException ex) { 5843 throw ex.rethrowFromSystemServer(); 5844 } 5845 // Watch for getting close to heap limit. 5846 BinderInternal.addGcWatcher(new Runnable() { 5847 @Override public void run() { 5848 if (!mSomeActivitiesChanged) { 5849 return; 5850 } 5851 Runtime runtime = Runtime.getRuntime(); 5852 long dalvikMax = runtime.maxMemory(); 5853 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); 5854 if (dalvikUsed > ((3*dalvikMax)/4)) { 5855 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) 5856 + " total=" + (runtime.totalMemory()/1024) 5857 + " used=" + (dalvikUsed/1024)); 5858 mSomeActivitiesChanged = false; 5859 try { 5860 mgr.releaseSomeActivities(mAppThread); 5861 } catch (RemoteException e) { 5862 throw e.rethrowFromSystemServer(); 5863 } 5864 } 5865 } 5866 }); 5867 } else { 5868 // Don't set application object here -- if the system crashes, 5869 // we can't display an alert, we just want to die die die. 5870 android.ddm.DdmHandleAppName.setAppName("system_process", 5871 UserHandle.myUserId()); 5872 try { 5873 mInstrumentation = new Instrumentation(); 5874 ContextImpl context = ContextImpl.createAppContext( 5875 this, getSystemContext().mPackageInfo); 5876 mInitialApplication = context.mPackageInfo.makeApplication(true, null); 5877 mInitialApplication.onCreate(); 5878 } catch (Exception e) { 5879 throw new RuntimeException( 5880 "Unable to instantiate Application():" + e.toString(), e); 5881 } 5882 } 5883 5884 // add dropbox logging to libcore 5885 DropBox.setReporter(new DropBoxReporter()); 5886 5887 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 5888 @Override 5889 public void onConfigurationChanged(Configuration newConfig) { 5890 synchronized (mResourcesManager) { 5891 // We need to apply this change to the resources 5892 // immediately, because upon returning the view 5893 // hierarchy will be informed about it. 5894 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { 5895 // This actually changed the resources! Tell 5896 // everyone about it. 5897 if (mPendingConfiguration == null || 5898 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 5899 mPendingConfiguration = newConfig; 5900 5901 sendMessage(H.CONFIGURATION_CHANGED, newConfig); 5902 } 5903 } 5904 } 5905 } 5906 @Override 5907 public void onLowMemory() { 5908 } 5909 @Override 5910 public void onTrimMemory(int level) { 5911 } 5912 }); 5913 } 5914 5915 public static ActivityThread systemMain() { 5916 // The system process on low-memory devices do not get to use hardware 5917 // accelerated drawing, since this can add too much overhead to the 5918 // process. 5919 if (!ActivityManager.isHighEndGfx()) { 5920 ThreadedRenderer.disable(true); 5921 } else { 5922 ThreadedRenderer.enableForegroundTrimming(); 5923 } 5924 ActivityThread thread = new ActivityThread(); 5925 thread.attach(true); 5926 return thread; 5927 } 5928 5929 public final void installSystemProviders(List<ProviderInfo> providers) { 5930 if (providers != null) { 5931 installContentProviders(mInitialApplication, providers); 5932 } 5933 } 5934 5935 public int getIntCoreSetting(String key, int defaultValue) { 5936 synchronized (mResourcesManager) { 5937 if (mCoreSettings != null) { 5938 return mCoreSettings.getInt(key, defaultValue); 5939 } 5940 return defaultValue; 5941 } 5942 } 5943 5944 private static class EventLoggingReporter implements EventLogger.Reporter { 5945 @Override 5946 public void report (int code, Object... list) { 5947 EventLog.writeEvent(code, list); 5948 } 5949 } 5950 5951 private class DropBoxReporter implements DropBox.Reporter { 5952 5953 private DropBoxManager dropBox; 5954 5955 public DropBoxReporter() {} 5956 5957 @Override 5958 public void addData(String tag, byte[] data, int flags) { 5959 ensureInitialized(); 5960 dropBox.addData(tag, data, flags); 5961 } 5962 5963 @Override 5964 public void addText(String tag, String data) { 5965 ensureInitialized(); 5966 dropBox.addText(tag, data); 5967 } 5968 5969 private synchronized void ensureInitialized() { 5970 if (dropBox == null) { 5971 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 5972 } 5973 } 5974 } 5975 5976 public static void main(String[] args) { 5977 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); 5978 SamplingProfilerIntegration.start(); 5979 5980 // CloseGuard defaults to true and can be quite spammy. We 5981 // disable it here, but selectively enable it later (via 5982 // StrictMode) on debug builds, but using DropBox, not logs. 5983 CloseGuard.setEnabled(false); 5984 5985 Environment.initForCurrentUser(); 5986 5987 // Set the reporter for event logging in libcore 5988 EventLogger.setReporter(new EventLoggingReporter()); 5989 5990 AndroidKeyStoreProvider.install(); 5991 5992 // Make sure TrustedCertificateStore looks in the right place for CA certificates 5993 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); 5994 TrustedCertificateStore.setDefaultUserDirectory(configDir); 5995 5996 Process.setArgV0("<pre-initialized>"); 5997 5998 Looper.prepareMainLooper(); 5999 6000 ActivityThread thread = new ActivityThread(); 6001 thread.attach(false); 6002 6003 if (sMainThreadHandler == null) { 6004 sMainThreadHandler = thread.getHandler(); 6005 } 6006 6007 if (false) { 6008 Looper.myLooper().setMessageLogging(new 6009 LogPrinter(Log.DEBUG, "ActivityThread")); 6010 } 6011 6012 // End of event ActivityThreadMain. 6013 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 6014 Looper.loop(); 6015 6016 throw new RuntimeException("Main thread loop unexpectedly exited"); 6017 } 6018} 6019