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