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