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