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