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