ActivityThread.java revision 8f3b174d90e3bf2093751fb1a1bd0603adac0222
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.service.voice.VoiceInteractionSession; 95import android.util.AndroidRuntimeException; 96import android.util.ArrayMap; 97import android.util.DisplayMetrics; 98import android.util.EventLog; 99import android.util.Log; 100import android.util.LogPrinter; 101import android.util.Pair; 102import android.util.PrintWriterPrinter; 103import android.util.Slog; 104import android.util.SparseIntArray; 105import android.util.SuperNotCalledException; 106import android.view.ContextThemeWrapper; 107import android.view.Display; 108import android.view.ThreadedRenderer; 109import android.view.View; 110import android.view.ViewDebug; 111import android.view.ViewManager; 112import android.view.ViewRootImpl; 113import android.view.Window; 114import android.view.WindowManager; 115import android.view.WindowManagerGlobal; 116import android.renderscript.RenderScriptCacheDir; 117import android.webkit.WebView; 118 119import com.android.internal.annotations.GuardedBy; 120import com.android.internal.app.IVoiceInteractor; 121import com.android.internal.content.ReferrerIntent; 122import com.android.internal.os.BinderInternal; 123import com.android.internal.os.RuntimeInit; 124import com.android.internal.os.SamplingProfilerIntegration; 125import com.android.internal.os.SomeArgs; 126import com.android.internal.util.ArrayUtils; 127import com.android.internal.util.FastPrintWriter; 128import com.android.org.conscrypt.OpenSSLSocketImpl; 129import com.android.org.conscrypt.TrustedCertificateStore; 130import com.google.android.collect.Lists; 131 132import java.io.File; 133import java.io.FileDescriptor; 134import java.io.FileOutputStream; 135import java.io.IOException; 136import java.io.PrintWriter; 137import java.lang.ref.WeakReference; 138import java.lang.reflect.Field; 139import java.net.InetAddress; 140import java.text.DateFormat; 141import java.util.ArrayList; 142import java.util.List; 143import java.util.Locale; 144import java.util.Map; 145import java.util.Objects; 146import java.util.TimeZone; 147 148import libcore.io.DropBox; 149import libcore.io.EventLogger; 150import libcore.io.IoUtils; 151import libcore.net.event.NetworkEventDispatcher; 152import dalvik.system.CloseGuard; 153import dalvik.system.VMDebug; 154import dalvik.system.VMRuntime; 155import org.apache.harmony.dalvik.ddmc.DdmVmInternal; 156 157final class RemoteServiceException extends AndroidRuntimeException { 158 public RemoteServiceException(String msg) { 159 super(msg); 160 } 161} 162 163/** 164 * This manages the execution of the main thread in an 165 * application process, scheduling and executing activities, 166 * broadcasts, and other operations on it as the activity 167 * manager requests. 168 * 169 * {@hide} 170 */ 171public final class ActivityThread { 172 /** @hide */ 173 public static final String TAG = "ActivityThread"; 174 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565; 175 static final boolean localLOGV = false; 176 static final boolean DEBUG_MESSAGES = false; 177 /** @hide */ 178 public static final boolean DEBUG_BROADCAST = false; 179 private static final boolean DEBUG_RESULTS = false; 180 private static final boolean DEBUG_BACKUP = false; 181 public static final boolean DEBUG_CONFIGURATION = false; 182 private static final boolean DEBUG_SERVICE = false; 183 private static final boolean DEBUG_MEMORY_TRIM = false; 184 private static final boolean DEBUG_PROVIDER = false; 185 private static final boolean DEBUG_ORDER = false; 186 private static final long MIN_TIME_BETWEEN_GCS = 5*1000; 187 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; 188 private static final int LOG_AM_ON_PAUSE_CALLED = 30021; 189 private static final int LOG_AM_ON_RESUME_CALLED = 30022; 190 private static final int LOG_AM_ON_STOP_CALLED = 30049; 191 192 /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */ 193 public static final int SERVICE_DONE_EXECUTING_ANON = 0; 194 /** Type for IActivityManager.serviceDoneExecuting: done with an onStart call */ 195 public static final int SERVICE_DONE_EXECUTING_START = 1; 196 /** Type for IActivityManager.serviceDoneExecuting: done stopping (destroying) service */ 197 public static final int SERVICE_DONE_EXECUTING_STOP = 2; 198 199 // Details for pausing activity. 200 private static final int USER_LEAVING = 1; 201 private static final int DONT_REPORT = 2; 202 203 // Whether to invoke an activity callback after delivering new configuration. 204 private static final boolean REPORT_TO_ACTIVITY = true; 205 206 private ContextImpl mSystemContext; 207 208 static volatile IPackageManager sPackageManager; 209 210 final ApplicationThread mAppThread = new ApplicationThread(); 211 final Looper mLooper = Looper.myLooper(); 212 final H mH = new H(); 213 final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>(); 214 // List of new activities (via ActivityRecord.nextIdle) that should 215 // be reported when next we idle. 216 ActivityClientRecord mNewActivities = null; 217 // Number of activities that are currently visible on-screen. 218 int mNumVisibleActivities = 0; 219 ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>(); 220 private int mLastSessionId; 221 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); 222 AppBindData mBoundApplication; 223 Profiler mProfiler; 224 int mCurDefaultDisplayDpi; 225 boolean mDensityCompatMode; 226 Configuration mConfiguration; 227 Configuration mCompatConfiguration; 228 Application mInitialApplication; 229 final ArrayList<Application> mAllApplications 230 = new ArrayList<Application>(); 231 // set of instantiated backup agents, keyed by package name 232 final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>(); 233 /** Reference to singleton {@link ActivityThread} */ 234 private static volatile ActivityThread sCurrentActivityThread; 235 Instrumentation mInstrumentation; 236 String mInstrumentationPackageName = null; 237 String mInstrumentationAppDir = null; 238 String[] mInstrumentationSplitAppDirs = null; 239 String mInstrumentationLibDir = null; 240 String mInstrumentedAppDir = null; 241 String[] mInstrumentedSplitAppDirs = null; 242 String mInstrumentedLibDir = null; 243 boolean mSystemThread = false; 244 boolean mJitEnabled = false; 245 boolean mSomeActivitiesChanged = false; 246 boolean mUpdatingSystemConfig = false; 247 248 // These can be accessed by multiple threads; mResourcesManager is the lock. 249 // XXX For now we keep around information about all packages we have 250 // seen, not removing entries from this map. 251 // NOTE: The activity and window managers need to call in to 252 // ActivityThread to do things like update resource configurations, 253 // which means this lock gets held while the activity and window managers 254 // holds their own lock. Thus you MUST NEVER call back into the activity manager 255 // or window manager or anything that depends on them while holding this lock. 256 // These LoadedApk are only valid for the userId that we're running as. 257 @GuardedBy("mResourcesManager") 258 final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<>(); 259 @GuardedBy("mResourcesManager") 260 final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<>(); 261 @GuardedBy("mResourcesManager") 262 final ArrayList<ActivityClientRecord> mRelaunchingActivities = new ArrayList<>(); 263 @GuardedBy("mResourcesManager") 264 Configuration mPendingConfiguration = null; 265 // Because we merge activity relaunch operations we can't depend on the ordering provided by 266 // the handler messages. We need to introduce secondary ordering mechanism, which will allow 267 // us to drop certain events, if we know that they happened before relaunch we already executed. 268 // This represents the order of receiving the request from AM. 269 @GuardedBy("mResourcesManager") 270 int mLifecycleSeq = 0; 271 272 private final ResourcesManager mResourcesManager; 273 274 private static final class ProviderKey { 275 final String authority; 276 final int userId; 277 278 public ProviderKey(String authority, int userId) { 279 this.authority = authority; 280 this.userId = userId; 281 } 282 283 @Override 284 public boolean equals(Object o) { 285 if (o instanceof ProviderKey) { 286 final ProviderKey other = (ProviderKey) o; 287 return Objects.equals(authority, other.authority) && userId == other.userId; 288 } 289 return false; 290 } 291 292 @Override 293 public int hashCode() { 294 return ((authority != null) ? authority.hashCode() : 0) ^ userId; 295 } 296 } 297 298 // The lock of mProviderMap protects the following variables. 299 final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap 300 = new ArrayMap<ProviderKey, ProviderClientRecord>(); 301 final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap 302 = new ArrayMap<IBinder, ProviderRefCount>(); 303 final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders 304 = new ArrayMap<IBinder, ProviderClientRecord>(); 305 final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName 306 = new ArrayMap<ComponentName, ProviderClientRecord>(); 307 308 final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners 309 = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); 310 311 final GcIdler mGcIdler = new GcIdler(); 312 boolean mGcIdlerScheduled = false; 313 314 static volatile Handler sMainThreadHandler; // set once in main() 315 316 Bundle mCoreSettings = null; 317 318 static final class ActivityClientRecord { 319 IBinder token; 320 int ident; 321 Intent intent; 322 String referrer; 323 IVoiceInteractor voiceInteractor; 324 Bundle state; 325 PersistableBundle persistentState; 326 Activity activity; 327 Window window; 328 Activity parent; 329 String embeddedID; 330 Activity.NonConfigurationInstances lastNonConfigurationInstances; 331 boolean paused; 332 boolean stopped; 333 boolean hideForNow; 334 Configuration newConfig; 335 Configuration createdConfig; 336 Configuration overrideConfig; 337 // Used for consolidating configs before sending on to Activity. 338 private Configuration tmpConfig = new Configuration(); 339 ActivityClientRecord nextIdle; 340 341 ProfilerInfo profilerInfo; 342 343 ActivityInfo activityInfo; 344 CompatibilityInfo compatInfo; 345 LoadedApk packageInfo; 346 347 List<ResultInfo> pendingResults; 348 List<ReferrerIntent> pendingIntents; 349 350 boolean startsNotResumed; 351 boolean isForward; 352 int pendingConfigChanges; 353 boolean onlyLocalRequest; 354 355 Window mPendingRemoveWindow; 356 WindowManager mPendingRemoveWindowManager; 357 boolean mPreserveWindow; 358 359 // Set for relaunch requests, indicates the order number of the relaunch operation, so it 360 // can be compared with other lifecycle operations. 361 int relaunchSeq = 0; 362 363 // Can only be accessed from the UI thread. This represents the latest processed message 364 // that is related to lifecycle events/ 365 int lastProcessedSeq = 0; 366 367 ActivityClientRecord() { 368 parent = null; 369 embeddedID = null; 370 paused = false; 371 stopped = false; 372 hideForNow = false; 373 nextIdle = null; 374 } 375 376 public boolean isPreHoneycomb() { 377 if (activity != null) { 378 return activity.getApplicationInfo().targetSdkVersion 379 < android.os.Build.VERSION_CODES.HONEYCOMB; 380 } 381 return false; 382 } 383 384 public boolean isPersistable() { 385 return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS; 386 } 387 388 public String toString() { 389 ComponentName componentName = intent != null ? intent.getComponent() : null; 390 return "ActivityRecord{" 391 + Integer.toHexString(System.identityHashCode(this)) 392 + " token=" + token + " " + (componentName == null 393 ? "no component name" : componentName.toShortString()) 394 + "}"; 395 } 396 397 public String getStateString() { 398 StringBuilder sb = new StringBuilder(); 399 sb.append("ActivityClientRecord{"); 400 sb.append("paused=").append(paused); 401 sb.append(", stopped=").append(stopped); 402 sb.append(", hideForNow=").append(hideForNow); 403 sb.append(", startsNotResumed=").append(startsNotResumed); 404 sb.append(", isForward=").append(isForward); 405 sb.append(", pendingConfigChanges=").append(pendingConfigChanges); 406 sb.append(", onlyLocalRequest=").append(onlyLocalRequest); 407 sb.append(", preserveWindow=").append(mPreserveWindow); 408 if (activity != null) { 409 sb.append(", Activity{"); 410 sb.append("resumed=").append(activity.mResumed); 411 sb.append(", stopped=").append(activity.mStopped); 412 sb.append(", finished=").append(activity.isFinishing()); 413 sb.append(", destroyed=").append(activity.isDestroyed()); 414 sb.append(", startedActivity=").append(activity.mStartedActivity); 415 sb.append(", temporaryPause=").append(activity.mTemporaryPause); 416 sb.append(", changingConfigurations=").append(activity.mChangingConfigurations); 417 sb.append(", visibleBehind=").append(activity.mVisibleBehind); 418 sb.append("}"); 419 } 420 sb.append("}"); 421 return sb.toString(); 422 } 423 } 424 425 final class ProviderClientRecord { 426 final String[] mNames; 427 final IContentProvider mProvider; 428 final ContentProvider mLocalProvider; 429 final ContentProviderHolder mHolder; 430 431 ProviderClientRecord(String[] names, IContentProvider provider, 432 ContentProvider localProvider, ContentProviderHolder holder) { 433 mNames = names; 434 mProvider = provider; 435 mLocalProvider = localProvider; 436 mHolder = holder; 437 } 438 } 439 440 static final class NewIntentData { 441 List<ReferrerIntent> intents; 442 IBinder token; 443 boolean andPause; 444 public String toString() { 445 return "NewIntentData{intents=" + intents + " token=" + token 446 + " andPause=" + andPause +"}"; 447 } 448 } 449 450 static final class ReceiverData extends BroadcastReceiver.PendingResult { 451 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras, 452 boolean ordered, boolean sticky, IBinder token, int sendingUser) { 453 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky, 454 token, sendingUser, intent.getFlags()); 455 this.intent = intent; 456 } 457 458 Intent intent; 459 ActivityInfo info; 460 CompatibilityInfo compatInfo; 461 public String toString() { 462 return "ReceiverData{intent=" + intent + " packageName=" + 463 info.packageName + " resultCode=" + getResultCode() 464 + " resultData=" + getResultData() + " resultExtras=" 465 + getResultExtras(false) + "}"; 466 } 467 } 468 469 static final class CreateBackupAgentData { 470 ApplicationInfo appInfo; 471 CompatibilityInfo compatInfo; 472 int backupMode; 473 public String toString() { 474 return "CreateBackupAgentData{appInfo=" + appInfo 475 + " backupAgent=" + appInfo.backupAgentName 476 + " mode=" + backupMode + "}"; 477 } 478 } 479 480 static final class CreateServiceData { 481 IBinder token; 482 ServiceInfo info; 483 CompatibilityInfo compatInfo; 484 Intent intent; 485 public String toString() { 486 return "CreateServiceData{token=" + token + " className=" 487 + info.name + " packageName=" + info.packageName 488 + " intent=" + intent + "}"; 489 } 490 } 491 492 static final class BindServiceData { 493 IBinder token; 494 Intent intent; 495 boolean rebind; 496 public String toString() { 497 return "BindServiceData{token=" + token + " intent=" + intent + "}"; 498 } 499 } 500 501 static final class ServiceArgsData { 502 IBinder token; 503 boolean taskRemoved; 504 int startId; 505 int flags; 506 Intent args; 507 public String toString() { 508 return "ServiceArgsData{token=" + token + " startId=" + startId 509 + " args=" + args + "}"; 510 } 511 } 512 513 static final class AppBindData { 514 LoadedApk info; 515 String processName; 516 ApplicationInfo appInfo; 517 List<ProviderInfo> providers; 518 ComponentName instrumentationName; 519 Bundle instrumentationArgs; 520 IInstrumentationWatcher instrumentationWatcher; 521 IUiAutomationConnection instrumentationUiAutomationConnection; 522 int debugMode; 523 boolean enableBinderTracking; 524 boolean trackAllocation; 525 boolean restrictedBackupMode; 526 boolean persistent; 527 Configuration config; 528 CompatibilityInfo compatInfo; 529 String buildSerial; 530 531 /** Initial values for {@link Profiler}. */ 532 ProfilerInfo initProfilerInfo; 533 534 public String toString() { 535 return "AppBindData{appInfo=" + appInfo + "}"; 536 } 537 } 538 539 static final class Profiler { 540 String profileFile; 541 ParcelFileDescriptor profileFd; 542 int samplingInterval; 543 boolean autoStopProfiler; 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 } 570 public void startProfiling() { 571 if (profileFd == null || profiling) { 572 return; 573 } 574 try { 575 int bufferSize = SystemProperties.getInt("debug.traceview-buffer-size-mb", 8); 576 VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(), 577 bufferSize * 1024 * 1024, 0, samplingInterval != 0, samplingInterval); 578 profiling = true; 579 } catch (RuntimeException e) { 580 Slog.w(TAG, "Profiling failed on path " + profileFile); 581 try { 582 profileFd.close(); 583 profileFd = null; 584 } catch (IOException e2) { 585 Slog.w(TAG, "Failure closing profile fd", e2); 586 } 587 } 588 } 589 public void stopProfiling() { 590 if (profiling) { 591 profiling = false; 592 Debug.stopMethodTracing(); 593 if (profileFd != null) { 594 try { 595 profileFd.close(); 596 } catch (IOException e) { 597 } 598 } 599 profileFd = null; 600 profileFile = null; 601 } 602 } 603 } 604 605 static final class DumpComponentInfo { 606 ParcelFileDescriptor fd; 607 IBinder token; 608 String prefix; 609 String[] args; 610 } 611 612 static final class ResultData { 613 IBinder token; 614 List<ResultInfo> results; 615 public String toString() { 616 return "ResultData{token=" + token + " results" + results + "}"; 617 } 618 } 619 620 static final class ContextCleanupInfo { 621 ContextImpl context; 622 String what; 623 String who; 624 } 625 626 static final class DumpHeapData { 627 String path; 628 ParcelFileDescriptor fd; 629 } 630 631 static final class UpdateCompatibilityData { 632 String pkg; 633 CompatibilityInfo info; 634 } 635 636 static final class RequestAssistContextExtras { 637 IBinder activityToken; 638 IBinder requestToken; 639 int requestType; 640 int sessionId; 641 int flags; 642 } 643 644 static final class ActivityConfigChangeData { 645 final IBinder activityToken; 646 final Configuration overrideConfig; 647 public ActivityConfigChangeData(IBinder token, Configuration config) { 648 activityToken = token; 649 overrideConfig = config; 650 } 651 } 652 653 private class ApplicationThread extends IApplicationThread.Stub { 654 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; 655 656 private int mLastProcessState = -1; 657 658 private void updatePendingConfiguration(Configuration config) { 659 synchronized (mResourcesManager) { 660 if (mPendingConfiguration == null || 661 mPendingConfiguration.isOtherSeqNewer(config)) { 662 mPendingConfiguration = config; 663 } 664 } 665 } 666 667 public final void schedulePauseActivity(IBinder token, boolean finished, 668 boolean userLeaving, int configChanges, boolean dontReport) { 669 int seq = getLifecycleSeq(); 670 if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this 671 + " operation received seq: " + seq); 672 sendMessage( 673 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, 674 token, 675 (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0), 676 configChanges, 677 seq); 678 } 679 680 public final void scheduleStopActivity(IBinder token, boolean showWindow, 681 int configChanges) { 682 int seq = getLifecycleSeq(); 683 if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this 684 + " operation received seq: " + seq); 685 sendMessage( 686 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, 687 token, 0, configChanges, seq); 688 } 689 690 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) { 691 sendMessage( 692 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW, 693 token); 694 } 695 696 public final void scheduleSleeping(IBinder token, boolean sleeping) { 697 sendMessage(H.SLEEPING, token, sleeping ? 1 : 0); 698 } 699 700 public final void scheduleResumeActivity(IBinder token, int processState, 701 boolean isForward, Bundle resumeArgs) { 702 int seq = getLifecycleSeq(); 703 if (DEBUG_ORDER) Slog.d(TAG, "resumeActivity " + ActivityThread.this 704 + " operation received seq: " + seq); 705 updateProcessState(processState, false); 706 sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq); 707 } 708 709 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) { 710 ResultData res = new ResultData(); 711 res.token = token; 712 res.results = results; 713 sendMessage(H.SEND_RESULT, res); 714 } 715 716 // we use token to identify this activity without having to send the 717 // activity itself back to the activity manager. (matters more with ipc) 718 @Override 719 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, 720 ActivityInfo info, Configuration curConfig, Configuration overrideConfig, 721 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, 722 int procState, Bundle state, PersistableBundle persistentState, 723 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 724 boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { 725 726 updateProcessState(procState, false); 727 728 ActivityClientRecord r = new ActivityClientRecord(); 729 730 r.token = token; 731 r.ident = ident; 732 r.intent = intent; 733 r.referrer = referrer; 734 r.voiceInteractor = voiceInteractor; 735 r.activityInfo = info; 736 r.compatInfo = compatInfo; 737 r.state = state; 738 r.persistentState = persistentState; 739 740 r.pendingResults = pendingResults; 741 r.pendingIntents = pendingNewIntents; 742 743 r.startsNotResumed = notResumed; 744 r.isForward = isForward; 745 746 r.profilerInfo = profilerInfo; 747 748 r.overrideConfig = overrideConfig; 749 updatePendingConfiguration(curConfig); 750 751 sendMessage(H.LAUNCH_ACTIVITY, r); 752 } 753 754 @Override 755 public final void scheduleRelaunchActivity(IBinder token, 756 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 757 int configChanges, boolean notResumed, Configuration config, 758 Configuration overrideConfig, boolean preserveWindow) { 759 requestRelaunchActivity(token, pendingResults, pendingNewIntents, 760 configChanges, notResumed, config, overrideConfig, true, preserveWindow); 761 } 762 763 public final void scheduleNewIntent( 764 List<ReferrerIntent> intents, IBinder token, boolean andPause) { 765 NewIntentData data = new NewIntentData(); 766 data.intents = intents; 767 data.token = token; 768 data.andPause = andPause; 769 770 sendMessage(H.NEW_INTENT, data); 771 } 772 773 public final void scheduleDestroyActivity(IBinder token, boolean finishing, 774 int configChanges) { 775 sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0, 776 configChanges); 777 } 778 779 public final void scheduleReceiver(Intent intent, ActivityInfo info, 780 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, 781 boolean sync, int sendingUser, int processState) { 782 updateProcessState(processState, false); 783 ReceiverData r = new ReceiverData(intent, resultCode, data, extras, 784 sync, false, mAppThread.asBinder(), sendingUser); 785 r.info = info; 786 r.compatInfo = compatInfo; 787 sendMessage(H.RECEIVER, r); 788 } 789 790 public final void scheduleCreateBackupAgent(ApplicationInfo app, 791 CompatibilityInfo compatInfo, int backupMode) { 792 CreateBackupAgentData d = new CreateBackupAgentData(); 793 d.appInfo = app; 794 d.compatInfo = compatInfo; 795 d.backupMode = backupMode; 796 797 sendMessage(H.CREATE_BACKUP_AGENT, d); 798 } 799 800 public final void scheduleDestroyBackupAgent(ApplicationInfo app, 801 CompatibilityInfo compatInfo) { 802 CreateBackupAgentData d = new CreateBackupAgentData(); 803 d.appInfo = app; 804 d.compatInfo = compatInfo; 805 806 sendMessage(H.DESTROY_BACKUP_AGENT, d); 807 } 808 809 public final void scheduleCreateService(IBinder token, 810 ServiceInfo info, CompatibilityInfo compatInfo, int processState) { 811 updateProcessState(processState, false); 812 CreateServiceData s = new CreateServiceData(); 813 s.token = token; 814 s.info = info; 815 s.compatInfo = compatInfo; 816 817 sendMessage(H.CREATE_SERVICE, s); 818 } 819 820 public final void scheduleBindService(IBinder token, Intent intent, 821 boolean rebind, int processState) { 822 updateProcessState(processState, false); 823 BindServiceData s = new BindServiceData(); 824 s.token = token; 825 s.intent = intent; 826 s.rebind = rebind; 827 828 if (DEBUG_SERVICE) 829 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" 830 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); 831 sendMessage(H.BIND_SERVICE, s); 832 } 833 834 public final void scheduleUnbindService(IBinder token, Intent intent) { 835 BindServiceData s = new BindServiceData(); 836 s.token = token; 837 s.intent = intent; 838 839 sendMessage(H.UNBIND_SERVICE, s); 840 } 841 842 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId, 843 int flags ,Intent args) { 844 ServiceArgsData s = new ServiceArgsData(); 845 s.token = token; 846 s.taskRemoved = taskRemoved; 847 s.startId = startId; 848 s.flags = flags; 849 s.args = args; 850 851 sendMessage(H.SERVICE_ARGS, s); 852 } 853 854 public final void scheduleStopService(IBinder token) { 855 sendMessage(H.STOP_SERVICE, token); 856 } 857 858 public final void bindApplication(String processName, ApplicationInfo appInfo, 859 List<ProviderInfo> providers, ComponentName instrumentationName, 860 ProfilerInfo profilerInfo, Bundle instrumentationArgs, 861 IInstrumentationWatcher instrumentationWatcher, 862 IUiAutomationConnection instrumentationUiConnection, int debugMode, 863 boolean enableBinderTracking, boolean trackAllocation, 864 boolean isRestrictedBackupMode, boolean persistent, Configuration config, 865 CompatibilityInfo compatInfo, Map services, Bundle coreSettings, 866 String buildSerial) { 867 868 if (services != null) { 869 // Setup the service cache in the ServiceManager 870 ServiceManager.initServiceCache(services); 871 } 872 873 setCoreSettings(coreSettings); 874 875 AppBindData data = new AppBindData(); 876 data.processName = processName; 877 data.appInfo = appInfo; 878 data.providers = providers; 879 data.instrumentationName = instrumentationName; 880 data.instrumentationArgs = instrumentationArgs; 881 data.instrumentationWatcher = instrumentationWatcher; 882 data.instrumentationUiAutomationConnection = instrumentationUiConnection; 883 data.debugMode = debugMode; 884 data.enableBinderTracking = enableBinderTracking; 885 data.trackAllocation = trackAllocation; 886 data.restrictedBackupMode = isRestrictedBackupMode; 887 data.persistent = persistent; 888 data.config = config; 889 data.compatInfo = compatInfo; 890 data.initProfilerInfo = profilerInfo; 891 data.buildSerial = buildSerial; 892 sendMessage(H.BIND_APPLICATION, data); 893 } 894 895 public final void scheduleExit() { 896 sendMessage(H.EXIT_APPLICATION, null); 897 } 898 899 public final void scheduleSuicide() { 900 sendMessage(H.SUICIDE, null); 901 } 902 903 public void scheduleConfigurationChanged(Configuration config) { 904 updatePendingConfiguration(config); 905 sendMessage(H.CONFIGURATION_CHANGED, config); 906 } 907 908 public void scheduleApplicationInfoChanged(ApplicationInfo ai) { 909 sendMessage(H.APPLICATION_INFO_CHANGED, ai); 910 } 911 912 public void updateTimeZone() { 913 TimeZone.setDefault(null); 914 } 915 916 public void clearDnsCache() { 917 // a non-standard API to get this to libcore 918 InetAddress.clearDnsCache(); 919 // Allow libcore to perform the necessary actions as it sees fit upon a network 920 // configuration change. 921 NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged(); 922 } 923 924 public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) { 925 final ConnectivityManager cm = ConnectivityManager.from(getSystemContext()); 926 final Network network = cm.getBoundNetworkForProcess(); 927 if (network != null) { 928 Proxy.setHttpProxySystemProperty(cm.getDefaultProxy()); 929 } else { 930 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl); 931 } 932 } 933 934 public void processInBackground() { 935 mH.removeMessages(H.GC_WHEN_IDLE); 936 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE)); 937 } 938 939 public void dumpService(ParcelFileDescriptor pfd, IBinder servicetoken, String[] args) { 940 DumpComponentInfo data = new DumpComponentInfo(); 941 try { 942 data.fd = pfd.dup(); 943 data.token = servicetoken; 944 data.args = args; 945 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/); 946 } catch (IOException e) { 947 Slog.w(TAG, "dumpService failed", e); 948 } finally { 949 IoUtils.closeQuietly(pfd); 950 } 951 } 952 953 // This function exists to make sure all receiver dispatching is 954 // correctly ordered, since these are one-way calls and the binder driver 955 // applies transaction ordering per object for such calls. 956 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, 957 int resultCode, String dataStr, Bundle extras, boolean ordered, 958 boolean sticky, int sendingUser, int processState) throws RemoteException { 959 updateProcessState(processState, false); 960 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, 961 sticky, sendingUser); 962 } 963 964 @Override 965 public void scheduleLowMemory() { 966 sendMessage(H.LOW_MEMORY, null); 967 } 968 969 @Override 970 public void scheduleActivityConfigurationChanged( 971 IBinder token, Configuration overrideConfig, boolean reportToActivity) { 972 sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, 973 new ActivityConfigChangeData(token, overrideConfig), reportToActivity ? 1 : 0); 974 } 975 976 @Override 977 public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 978 sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType); 979 } 980 981 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) { 982 DumpHeapData dhd = new DumpHeapData(); 983 dhd.path = path; 984 dhd.fd = fd; 985 sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/); 986 } 987 988 public void attachAgent(String agent) { 989 sendMessage(H.ATTACH_AGENT, agent); 990 } 991 992 public void setSchedulingGroup(int group) { 993 // Note: do this immediately, since going into the foreground 994 // should happen regardless of what pending work we have to do 995 // and the activity manager will wait for us to report back that 996 // we are done before sending us to the background. 997 try { 998 Process.setProcessGroup(Process.myPid(), group); 999 } catch (Exception e) { 1000 Slog.w(TAG, "Failed setting process group to " + group, e); 1001 } 1002 } 1003 1004 public void dispatchPackageBroadcast(int cmd, String[] packages) { 1005 sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd); 1006 } 1007 1008 public void scheduleCrash(String msg) { 1009 sendMessage(H.SCHEDULE_CRASH, msg); 1010 } 1011 1012 public void dumpActivity(ParcelFileDescriptor pfd, IBinder activitytoken, 1013 String prefix, String[] args) { 1014 DumpComponentInfo data = new DumpComponentInfo(); 1015 try { 1016 data.fd = pfd.dup(); 1017 data.token = activitytoken; 1018 data.prefix = prefix; 1019 data.args = args; 1020 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/); 1021 } catch (IOException e) { 1022 Slog.w(TAG, "dumpActivity failed", e); 1023 } finally { 1024 IoUtils.closeQuietly(pfd); 1025 } 1026 } 1027 1028 public void dumpProvider(ParcelFileDescriptor pfd, IBinder providertoken, 1029 String[] args) { 1030 DumpComponentInfo data = new DumpComponentInfo(); 1031 try { 1032 data.fd = pfd.dup(); 1033 data.token = providertoken; 1034 data.args = args; 1035 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/); 1036 } catch (IOException e) { 1037 Slog.w(TAG, "dumpProvider failed", e); 1038 } finally { 1039 IoUtils.closeQuietly(pfd); 1040 } 1041 } 1042 1043 @Override 1044 public void dumpMemInfo(ParcelFileDescriptor pfd, Debug.MemoryInfo mem, boolean checkin, 1045 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, 1046 boolean dumpUnreachable, String[] args) { 1047 FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor()); 1048 PrintWriter pw = new FastPrintWriter(fout); 1049 try { 1050 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable); 1051 } finally { 1052 pw.flush(); 1053 IoUtils.closeQuietly(pfd); 1054 } 1055 } 1056 1057 private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 1058 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable) { 1059 long nativeMax = Debug.getNativeHeapSize() / 1024; 1060 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; 1061 long nativeFree = Debug.getNativeHeapFreeSize() / 1024; 1062 1063 Runtime runtime = Runtime.getRuntime(); 1064 runtime.gc(); // Do GC since countInstancesOfClass counts unreachable objects. 1065 long dalvikMax = runtime.totalMemory() / 1024; 1066 long dalvikFree = runtime.freeMemory() / 1024; 1067 long dalvikAllocated = dalvikMax - dalvikFree; 1068 1069 Class[] classesToCount = new Class[] { 1070 ContextImpl.class, 1071 Activity.class, 1072 WebView.class, 1073 OpenSSLSocketImpl.class 1074 }; 1075 long[] instanceCounts = VMDebug.countInstancesOfClasses(classesToCount, true); 1076 long appContextInstanceCount = instanceCounts[0]; 1077 long activityInstanceCount = instanceCounts[1]; 1078 long webviewInstanceCount = instanceCounts[2]; 1079 long openSslSocketCount = instanceCounts[3]; 1080 1081 long viewInstanceCount = ViewDebug.getViewInstanceCount(); 1082 long viewRootInstanceCount = ViewDebug.getViewRootImplCount(); 1083 int globalAssetCount = AssetManager.getGlobalAssetCount(); 1084 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount(); 1085 int binderLocalObjectCount = Debug.getBinderLocalObjectCount(); 1086 int binderProxyObjectCount = Debug.getBinderProxyObjectCount(); 1087 int binderDeathObjectCount = Debug.getBinderDeathObjectCount(); 1088 long parcelSize = Parcel.getGlobalAllocSize(); 1089 long parcelCount = Parcel.getGlobalAllocCount(); 1090 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo(); 1091 1092 dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, 1093 Process.myPid(), 1094 (mBoundApplication != null) ? mBoundApplication.processName : "unknown", 1095 nativeMax, nativeAllocated, nativeFree, 1096 dalvikMax, dalvikAllocated, dalvikFree); 1097 1098 if (checkin) { 1099 // NOTE: if you change anything significant below, also consider changing 1100 // ACTIVITY_THREAD_CHECKIN_VERSION. 1101 1102 // Object counts 1103 pw.print(viewInstanceCount); pw.print(','); 1104 pw.print(viewRootInstanceCount); pw.print(','); 1105 pw.print(appContextInstanceCount); pw.print(','); 1106 pw.print(activityInstanceCount); pw.print(','); 1107 1108 pw.print(globalAssetCount); pw.print(','); 1109 pw.print(globalAssetManagerCount); pw.print(','); 1110 pw.print(binderLocalObjectCount); pw.print(','); 1111 pw.print(binderProxyObjectCount); pw.print(','); 1112 1113 pw.print(binderDeathObjectCount); pw.print(','); 1114 pw.print(openSslSocketCount); pw.print(','); 1115 1116 // SQL 1117 pw.print(stats.memoryUsed / 1024); pw.print(','); 1118 pw.print(stats.memoryUsed / 1024); pw.print(','); 1119 pw.print(stats.pageCacheOverflow / 1024); pw.print(','); 1120 pw.print(stats.largestMemAlloc / 1024); 1121 for (int i = 0; i < stats.dbStats.size(); i++) { 1122 DbStats dbStats = stats.dbStats.get(i); 1123 pw.print(','); pw.print(dbStats.dbName); 1124 pw.print(','); pw.print(dbStats.pageSize); 1125 pw.print(','); pw.print(dbStats.dbSize); 1126 pw.print(','); pw.print(dbStats.lookaside); 1127 pw.print(','); pw.print(dbStats.cache); 1128 pw.print(','); pw.print(dbStats.cache); 1129 } 1130 pw.println(); 1131 1132 return; 1133 } 1134 1135 pw.println(" "); 1136 pw.println(" Objects"); 1137 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:", 1138 viewRootInstanceCount); 1139 1140 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount, 1141 "Activities:", activityInstanceCount); 1142 1143 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount, 1144 "AssetManagers:", globalAssetManagerCount); 1145 1146 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount, 1147 "Proxy Binders:", binderProxyObjectCount); 1148 printRow(pw, TWO_COUNT_COLUMNS, "Parcel memory:", parcelSize/1024, 1149 "Parcel count:", parcelCount); 1150 printRow(pw, TWO_COUNT_COLUMNS, "Death Recipients:", binderDeathObjectCount, 1151 "OpenSSL Sockets:", openSslSocketCount); 1152 printRow(pw, ONE_COUNT_COLUMN, "WebViews:", webviewInstanceCount); 1153 1154 // SQLite mem info 1155 pw.println(" "); 1156 pw.println(" SQL"); 1157 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024); 1158 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:", 1159 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024); 1160 pw.println(" "); 1161 int N = stats.dbStats.size(); 1162 if (N > 0) { 1163 pw.println(" DATABASES"); 1164 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache", 1165 "Dbname"); 1166 for (int i = 0; i < N; i++) { 1167 DbStats dbStats = stats.dbStats.get(i); 1168 printRow(pw, DB_INFO_FORMAT, 1169 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ", 1170 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ", 1171 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ", 1172 dbStats.cache, dbStats.dbName); 1173 } 1174 } 1175 1176 // Asset details. 1177 String assetAlloc = AssetManager.getAssetAllocations(); 1178 if (assetAlloc != null) { 1179 pw.println(" "); 1180 pw.println(" Asset Allocations"); 1181 pw.print(assetAlloc); 1182 } 1183 1184 // Unreachable native memory 1185 if (dumpUnreachable) { 1186 boolean showContents = ((mBoundApplication != null) 1187 && ((mBoundApplication.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0)) 1188 || android.os.Build.IS_DEBUGGABLE; 1189 pw.println(" "); 1190 pw.println(" Unreachable memory"); 1191 pw.print(Debug.getUnreachableMemory(100, showContents)); 1192 } 1193 } 1194 1195 @Override 1196 public void dumpGfxInfo(ParcelFileDescriptor pfd, String[] args) { 1197 nDumpGraphicsInfo(pfd.getFileDescriptor()); 1198 WindowManagerGlobal.getInstance().dumpGfxInfo(pfd.getFileDescriptor(), args); 1199 IoUtils.closeQuietly(pfd); 1200 } 1201 1202 private void dumpDatabaseInfo(ParcelFileDescriptor pfd, String[] args) { 1203 PrintWriter pw = new FastPrintWriter( 1204 new FileOutputStream(pfd.getFileDescriptor())); 1205 PrintWriterPrinter printer = new PrintWriterPrinter(pw); 1206 SQLiteDebug.dump(printer, args); 1207 pw.flush(); 1208 } 1209 1210 @Override 1211 public void dumpDbInfo(final ParcelFileDescriptor pfd, final String[] args) { 1212 if (mSystemThread) { 1213 // Ensure this invocation is asynchronous to prevent writer waiting if buffer cannot 1214 // be consumed. But it must duplicate the file descriptor first, since caller might 1215 // be closing it. 1216 final ParcelFileDescriptor dup; 1217 try { 1218 dup = pfd.dup(); 1219 } catch (IOException e) { 1220 Log.w(TAG, "Could not dup FD " + pfd.getFileDescriptor().getInt$()); 1221 return; 1222 } finally { 1223 IoUtils.closeQuietly(pfd); 1224 } 1225 1226 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() { 1227 @Override 1228 public void run() { 1229 try { 1230 dumpDatabaseInfo(dup, args); 1231 } finally { 1232 IoUtils.closeQuietly(dup); 1233 } 1234 } 1235 }); 1236 } else { 1237 dumpDatabaseInfo(pfd, args); 1238 IoUtils.closeQuietly(pfd); 1239 } 1240 } 1241 1242 @Override 1243 public void unstableProviderDied(IBinder provider) { 1244 sendMessage(H.UNSTABLE_PROVIDER_DIED, provider); 1245 } 1246 1247 @Override 1248 public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, 1249 int requestType, int sessionId, int flags) { 1250 RequestAssistContextExtras cmd = new RequestAssistContextExtras(); 1251 cmd.activityToken = activityToken; 1252 cmd.requestToken = requestToken; 1253 cmd.requestType = requestType; 1254 cmd.sessionId = sessionId; 1255 cmd.flags = flags; 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 Activity activity = null; 2620 try { 2621 java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); 2622 activity = mInstrumentation.newActivity( 2623 cl, component.getClassName(), r.intent); 2624 StrictMode.incrementExpectedActivityCount(activity.getClass()); 2625 r.intent.setExtrasClassLoader(cl); 2626 r.intent.prepareToEnterProcess(); 2627 if (r.state != null) { 2628 r.state.setClassLoader(cl); 2629 } 2630 } catch (Exception e) { 2631 if (!mInstrumentation.onException(activity, e)) { 2632 throw new RuntimeException( 2633 "Unable to instantiate activity " + component 2634 + ": " + e.toString(), e); 2635 } 2636 } 2637 2638 try { 2639 Application app = r.packageInfo.makeApplication(false, mInstrumentation); 2640 2641 if (localLOGV) Slog.v(TAG, "Performing launch of " + r); 2642 if (localLOGV) Slog.v( 2643 TAG, r + ": app=" + app 2644 + ", appName=" + app.getPackageName() 2645 + ", pkg=" + r.packageInfo.getPackageName() 2646 + ", comp=" + r.intent.getComponent().toShortString() 2647 + ", dir=" + r.packageInfo.getAppDir()); 2648 2649 if (activity != null) { 2650 Context appContext = createBaseContextForActivity(r, activity); 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 activity.attach(appContext, this, getInstrumentation(), r.token, 2665 r.ident, app, r.intent, r.activityInfo, title, r.parent, 2666 r.embeddedID, r.lastNonConfigurationInstances, config, 2667 r.referrer, r.voiceInteractor, window); 2668 2669 if (customIntent != null) { 2670 activity.mIntent = customIntent; 2671 } 2672 r.lastNonConfigurationInstances = null; 2673 activity.mStartedActivity = false; 2674 int theme = r.activityInfo.getThemeResource(); 2675 if (theme != 0) { 2676 activity.setTheme(theme); 2677 } 2678 2679 activity.mCalled = false; 2680 if (r.isPersistable()) { 2681 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); 2682 } else { 2683 mInstrumentation.callActivityOnCreate(activity, r.state); 2684 } 2685 if (!activity.mCalled) { 2686 throw new SuperNotCalledException( 2687 "Activity " + r.intent.getComponent().toShortString() + 2688 " did not call through to super.onCreate()"); 2689 } 2690 r.activity = activity; 2691 r.stopped = true; 2692 if (!r.activity.mFinished) { 2693 activity.performStart(); 2694 r.stopped = false; 2695 } 2696 if (!r.activity.mFinished) { 2697 if (r.isPersistable()) { 2698 if (r.state != null || r.persistentState != null) { 2699 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, 2700 r.persistentState); 2701 } 2702 } else if (r.state != null) { 2703 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); 2704 } 2705 } 2706 if (!r.activity.mFinished) { 2707 activity.mCalled = false; 2708 if (r.isPersistable()) { 2709 mInstrumentation.callActivityOnPostCreate(activity, r.state, 2710 r.persistentState); 2711 } else { 2712 mInstrumentation.callActivityOnPostCreate(activity, r.state); 2713 } 2714 if (!activity.mCalled) { 2715 throw new SuperNotCalledException( 2716 "Activity " + r.intent.getComponent().toShortString() + 2717 " did not call through to super.onPostCreate()"); 2718 } 2719 } 2720 } 2721 r.paused = true; 2722 2723 mActivities.put(r.token, r); 2724 2725 } catch (SuperNotCalledException e) { 2726 throw e; 2727 2728 } catch (Exception e) { 2729 if (!mInstrumentation.onException(activity, e)) { 2730 throw new RuntimeException( 2731 "Unable to start activity " + component 2732 + ": " + e.toString(), e); 2733 } 2734 } 2735 2736 return activity; 2737 } 2738 2739 private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) { 2740 int displayId = Display.DEFAULT_DISPLAY; 2741 try { 2742 displayId = ActivityManager.getService().getActivityDisplayId(r.token); 2743 } catch (RemoteException e) { 2744 throw e.rethrowFromSystemServer(); 2745 } 2746 2747 ContextImpl appContext = ContextImpl.createActivityContext( 2748 this, r.packageInfo, r.token, displayId, r.overrideConfig); 2749 appContext.setOuterContext(activity); 2750 Context baseContext = appContext; 2751 2752 final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 2753 // For debugging purposes, if the activity's package name contains the value of 2754 // the "debug.use-second-display" system property as a substring, then show 2755 // its content on a secondary display if there is one. 2756 String pkgName = SystemProperties.get("debug.second-display.pkg"); 2757 if (pkgName != null && !pkgName.isEmpty() 2758 && r.packageInfo.mPackageName.contains(pkgName)) { 2759 for (int id : dm.getDisplayIds()) { 2760 if (id != Display.DEFAULT_DISPLAY) { 2761 Display display = 2762 dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id)); 2763 baseContext = appContext.createDisplayContext(display); 2764 break; 2765 } 2766 } 2767 } 2768 return baseContext; 2769 } 2770 2771 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { 2772 // If we are getting ready to gc after going to the background, well 2773 // we are back active so skip it. 2774 unscheduleGcIdler(); 2775 mSomeActivitiesChanged = true; 2776 2777 if (r.profilerInfo != null) { 2778 mProfiler.setProfiler(r.profilerInfo); 2779 mProfiler.startProfiling(); 2780 } 2781 2782 // Make sure we are running with the most recent config. 2783 handleConfigurationChanged(null, null); 2784 2785 if (localLOGV) Slog.v( 2786 TAG, "Handling launch of " + r); 2787 2788 // Initialize before creating the activity 2789 WindowManagerGlobal.initialize(); 2790 2791 Activity a = performLaunchActivity(r, customIntent); 2792 2793 if (a != null) { 2794 r.createdConfig = new Configuration(mConfiguration); 2795 reportSizeConfigurations(r); 2796 Bundle oldState = r.state; 2797 handleResumeActivity(r.token, false, r.isForward, 2798 !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); 2799 2800 if (!r.activity.mFinished && r.startsNotResumed) { 2801 // The activity manager actually wants this one to start out paused, because it 2802 // needs to be visible but isn't in the foreground. We accomplish this by going 2803 // through the normal startup (because activities expect to go through onResume() 2804 // the first time they run, before their window is displayed), and then pausing it. 2805 // However, in this case we do -not- need to do the full pause cycle (of freezing 2806 // and such) because the activity manager assumes it can just retain the current 2807 // state it has. 2808 performPauseActivityIfNeeded(r, reason); 2809 2810 // We need to keep around the original state, in case we need to be created again. 2811 // But we only do this for pre-Honeycomb apps, which always save their state when 2812 // pausing, so we can not have them save their state when restarting from a paused 2813 // state. For HC and later, we want to (and can) let the state be saved as the 2814 // normal part of stopping the activity. 2815 if (r.isPreHoneycomb()) { 2816 r.state = oldState; 2817 } 2818 } 2819 } else { 2820 // If there was an error, for any reason, tell the activity manager to stop us. 2821 try { 2822 ActivityManager.getService() 2823 .finishActivity(r.token, Activity.RESULT_CANCELED, null, 2824 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 2825 } catch (RemoteException ex) { 2826 throw ex.rethrowFromSystemServer(); 2827 } 2828 } 2829 } 2830 2831 private void reportSizeConfigurations(ActivityClientRecord r) { 2832 Configuration[] configurations = r.activity.getResources().getSizeConfigurations(); 2833 if (configurations == null) { 2834 return; 2835 } 2836 SparseIntArray horizontal = new SparseIntArray(); 2837 SparseIntArray vertical = new SparseIntArray(); 2838 SparseIntArray smallest = new SparseIntArray(); 2839 for (int i = configurations.length - 1; i >= 0; i--) { 2840 Configuration config = configurations[i]; 2841 if (config.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { 2842 vertical.put(config.screenHeightDp, 0); 2843 } 2844 if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) { 2845 horizontal.put(config.screenWidthDp, 0); 2846 } 2847 if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { 2848 smallest.put(config.smallestScreenWidthDp, 0); 2849 } 2850 } 2851 try { 2852 ActivityManager.getService().reportSizeConfigurations(r.token, 2853 horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys()); 2854 } catch (RemoteException ex) { 2855 throw ex.rethrowFromSystemServer(); 2856 } 2857 2858 } 2859 2860 private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) { 2861 final int N = intents.size(); 2862 for (int i=0; i<N; i++) { 2863 ReferrerIntent intent = intents.get(i); 2864 intent.setExtrasClassLoader(r.activity.getClassLoader()); 2865 intent.prepareToEnterProcess(); 2866 r.activity.mFragments.noteStateNotSaved(); 2867 mInstrumentation.callActivityOnNewIntent(r.activity, intent); 2868 } 2869 } 2870 2871 void performNewIntents(IBinder token, List<ReferrerIntent> intents, boolean andPause) { 2872 final ActivityClientRecord r = mActivities.get(token); 2873 if (r == null) { 2874 return; 2875 } 2876 2877 final boolean resumed = !r.paused; 2878 if (resumed) { 2879 r.activity.mTemporaryPause = true; 2880 mInstrumentation.callActivityOnPause(r.activity); 2881 } 2882 deliverNewIntents(r, intents); 2883 if (resumed) { 2884 r.activity.performResume(); 2885 r.activity.mTemporaryPause = false; 2886 } 2887 2888 if (r.paused && andPause) { 2889 // In this case the activity was in the paused state when we delivered the intent, 2890 // to guarantee onResume gets called after onNewIntent we temporarily resume the 2891 // activity and pause again as the caller wanted. 2892 performResumeActivity(token, false, "performNewIntents"); 2893 performPauseActivityIfNeeded(r, "performNewIntents"); 2894 } 2895 } 2896 2897 private void handleNewIntent(NewIntentData data) { 2898 performNewIntents(data.token, data.intents, data.andPause); 2899 } 2900 2901 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { 2902 // Filling for auto-fill has a few differences: 2903 // - it does not need an AssistContent 2904 // - it does not call onProvideAssistData() 2905 // - it needs an IAutoFillCallback 2906 // - it sets the flags so views can provide autofill-specific data (such as passwords) 2907 boolean forAutoFill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTO_FILL 2908 || cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTO_FILL_SAVE; 2909 2910 // TODO(b/33197203): decide if lastSessionId logic applies to auto-fill sessions 2911 if (mLastSessionId != cmd.sessionId) { 2912 // Clear the existing structures 2913 mLastSessionId = cmd.sessionId; 2914 for (int i = mLastAssistStructures.size() - 1; i >= 0; i--) { 2915 AssistStructure structure = mLastAssistStructures.get(i).get(); 2916 if (structure != null) { 2917 structure.clearSendChannel(); 2918 } 2919 mLastAssistStructures.remove(i); 2920 } 2921 } 2922 2923 Bundle data = new Bundle(); 2924 AssistStructure structure = null; 2925 AssistContent content = forAutoFill ? null : new AssistContent(); 2926 ActivityClientRecord r = mActivities.get(cmd.activityToken); 2927 Uri referrer = null; 2928 if (r != null) { 2929 if (!forAutoFill) { 2930 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data); 2931 r.activity.onProvideAssistData(data); 2932 referrer = r.activity.onProvideReferrer(); 2933 } 2934 if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutoFill) { 2935 structure = new AssistStructure(r.activity, cmd.flags); 2936 Intent activityIntent = r.activity.getIntent(); 2937 if (forAutoFill) { 2938 data.putInt(VoiceInteractionSession.KEY_FLAGS, cmd.flags); 2939 } 2940 boolean addAutoFillCallback = false; 2941 // TODO(b/33197203): re-evaluate conditions below for auto-fill. In particular, 2942 // FLAG_SECURE might be allowed on AUTO_FILL but not on AUTO_FILL_SAVE) 2943 boolean notSecure = r.window == null || 2944 (r.window.getAttributes().flags 2945 & WindowManager.LayoutParams.FLAG_SECURE) == 0; 2946 if (activityIntent != null && notSecure) { 2947 if (forAutoFill) { 2948 addAutoFillCallback = true; 2949 } else { 2950 Intent intent = new Intent(activityIntent); 2951 intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION 2952 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)); 2953 intent.removeUnsafeExtras(); 2954 content.setDefaultIntent(intent); 2955 } 2956 } else { 2957 if (!forAutoFill) { 2958 content.setDefaultIntent(new Intent()); 2959 } else { 2960 // activityIntent is unlikely to be null, but if it is, we should still 2961 // set the auto-fill callback. 2962 addAutoFillCallback = notSecure; 2963 } 2964 } 2965 if (!forAutoFill) { 2966 r.activity.onProvideAssistContent(content); 2967 } else if (addAutoFillCallback) { 2968 IAutoFillAppCallback cb = r.activity.getAutoFillCallback().get(); 2969 if (cb != null) { 2970 data.putBinder(AutoFillService.KEY_CALLBACK, cb.asBinder()); 2971 } else { 2972 Slog.w(TAG, "handleRequestAssistContextExtras(): callback was GCed"); 2973 } 2974 } 2975 } 2976 } 2977 if (structure == null) { 2978 structure = new AssistStructure(); 2979 } 2980 // TODO(b/33197203): decide if lastSessionId logic applies to auto-fill sessions 2981 mLastAssistStructures.add(new WeakReference<>(structure)); 2982 IActivityManager mgr = ActivityManager.getService(); 2983 try { 2984 mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer); 2985 } catch (RemoteException e) { 2986 throw e.rethrowFromSystemServer(); 2987 } 2988 } 2989 2990 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 2991 ActivityClientRecord r = mActivities.get(token); 2992 if (r != null) { 2993 r.activity.onTranslucentConversionComplete(drawComplete); 2994 } 2995 } 2996 2997 public void onNewActivityOptions(IBinder token, ActivityOptions options) { 2998 ActivityClientRecord r = mActivities.get(token); 2999 if (r != null) { 3000 r.activity.onNewActivityOptions(options); 3001 } 3002 } 3003 3004 public void handleCancelVisibleBehind(IBinder token) { 3005 ActivityClientRecord r = mActivities.get(token); 3006 if (r != null) { 3007 mSomeActivitiesChanged = true; 3008 final Activity activity = r.activity; 3009 if (activity.mVisibleBehind) { 3010 activity.mCalled = false; 3011 activity.onVisibleBehindCanceled(); 3012 // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed. 3013 if (!activity.mCalled) { 3014 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() + 3015 " did not call through to super.onVisibleBehindCanceled()"); 3016 } 3017 activity.mVisibleBehind = false; 3018 } 3019 } 3020 try { 3021 ActivityManager.getService().backgroundResourcesReleased(token); 3022 } catch (RemoteException e) { 3023 throw e.rethrowFromSystemServer(); 3024 } 3025 } 3026 3027 public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) { 3028 ActivityClientRecord r = mActivities.get(token); 3029 if (r != null) { 3030 r.activity.onBackgroundVisibleBehindChanged(visible); 3031 } 3032 } 3033 3034 public void handleInstallProvider(ProviderInfo info) { 3035 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3036 try { 3037 installContentProviders(mInitialApplication, Lists.newArrayList(info)); 3038 } finally { 3039 StrictMode.setThreadPolicy(oldPolicy); 3040 } 3041 } 3042 3043 private void handleEnterAnimationComplete(IBinder token) { 3044 ActivityClientRecord r = mActivities.get(token); 3045 if (r != null) { 3046 r.activity.dispatchEnterAnimationComplete(); 3047 } 3048 } 3049 3050 private void handleStartBinderTracking() { 3051 Binder.enableTracing(); 3052 } 3053 3054 private void handleStopBinderTrackingAndDump(ParcelFileDescriptor fd) { 3055 try { 3056 Binder.disableTracing(); 3057 Binder.getTransactionTracker().writeTracesToFile(fd); 3058 } finally { 3059 IoUtils.closeQuietly(fd); 3060 Binder.getTransactionTracker().clearTraces(); 3061 } 3062 } 3063 3064 private void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) { 3065 final ActivityClientRecord r = mActivities.get(token); 3066 if (r != null) { 3067 r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode); 3068 } 3069 } 3070 3071 private void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode) { 3072 final ActivityClientRecord r = mActivities.get(token); 3073 if (r != null) { 3074 r.activity.dispatchPictureInPictureModeChanged(isInPipMode); 3075 } 3076 } 3077 3078 private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) { 3079 final ActivityClientRecord r = mActivities.get(token); 3080 if (r != null) { 3081 r.voiceInteractor = interactor; 3082 r.activity.setVoiceInteractor(interactor); 3083 if (interactor == null) { 3084 r.activity.onLocalVoiceInteractionStopped(); 3085 } else { 3086 r.activity.onLocalVoiceInteractionStarted(); 3087 } 3088 } 3089 } 3090 3091 static final void handleAttachAgent(String agent) { 3092 try { 3093 VMDebug.attachAgent(agent); 3094 } catch (IOException e) { 3095 Slog.e(TAG, "Attaching agent failed: " + agent); 3096 } 3097 } 3098 3099 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); 3100 3101 /** 3102 * Return the Intent that's currently being handled by a 3103 * BroadcastReceiver on this thread, or null if none. 3104 * @hide 3105 */ 3106 public static Intent getIntentBeingBroadcast() { 3107 return sCurrentBroadcastIntent.get(); 3108 } 3109 3110 private void handleReceiver(ReceiverData data) { 3111 // If we are getting ready to gc after going to the background, well 3112 // we are back active so skip it. 3113 unscheduleGcIdler(); 3114 3115 String component = data.intent.getComponent().getClassName(); 3116 3117 LoadedApk packageInfo = getPackageInfoNoCheck( 3118 data.info.applicationInfo, data.compatInfo); 3119 3120 IActivityManager mgr = ActivityManager.getService(); 3121 3122 BroadcastReceiver receiver; 3123 try { 3124 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 3125 data.intent.setExtrasClassLoader(cl); 3126 data.intent.prepareToEnterProcess(); 3127 data.setExtrasClassLoader(cl); 3128 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance(); 3129 } catch (Exception e) { 3130 if (DEBUG_BROADCAST) Slog.i(TAG, 3131 "Finishing failed broadcast to " + data.intent.getComponent()); 3132 data.sendFinished(mgr); 3133 throw new RuntimeException( 3134 "Unable to instantiate receiver " + component 3135 + ": " + e.toString(), e); 3136 } 3137 3138 try { 3139 Application app = packageInfo.makeApplication(false, mInstrumentation); 3140 3141 if (localLOGV) Slog.v( 3142 TAG, "Performing receive of " + data.intent 3143 + ": app=" + app 3144 + ", appName=" + app.getPackageName() 3145 + ", pkg=" + packageInfo.getPackageName() 3146 + ", comp=" + data.intent.getComponent().toShortString() 3147 + ", dir=" + packageInfo.getAppDir()); 3148 3149 ContextImpl context = (ContextImpl)app.getBaseContext(); 3150 sCurrentBroadcastIntent.set(data.intent); 3151 receiver.setPendingResult(data); 3152 receiver.onReceive(context.getReceiverRestrictedContext(), 3153 data.intent); 3154 } catch (Exception e) { 3155 if (DEBUG_BROADCAST) Slog.i(TAG, 3156 "Finishing failed broadcast to " + data.intent.getComponent()); 3157 data.sendFinished(mgr); 3158 if (!mInstrumentation.onException(receiver, e)) { 3159 throw new RuntimeException( 3160 "Unable to start receiver " + component 3161 + ": " + e.toString(), e); 3162 } 3163 } finally { 3164 sCurrentBroadcastIntent.set(null); 3165 } 3166 3167 if (receiver.getPendingResult() != null) { 3168 data.finish(); 3169 } 3170 } 3171 3172 // Instantiate a BackupAgent and tell it that it's alive 3173 private void handleCreateBackupAgent(CreateBackupAgentData data) { 3174 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); 3175 3176 // Sanity check the requested target package's uid against ours 3177 try { 3178 PackageInfo requestedPackage = getPackageManager().getPackageInfo( 3179 data.appInfo.packageName, 0, UserHandle.myUserId()); 3180 if (requestedPackage.applicationInfo.uid != Process.myUid()) { 3181 Slog.w(TAG, "Asked to instantiate non-matching package " 3182 + data.appInfo.packageName); 3183 return; 3184 } 3185 } catch (RemoteException e) { 3186 throw e.rethrowFromSystemServer(); 3187 } 3188 3189 // no longer idle; we have backup work to do 3190 unscheduleGcIdler(); 3191 3192 // instantiate the BackupAgent class named in the manifest 3193 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 3194 String packageName = packageInfo.mPackageName; 3195 if (packageName == null) { 3196 Slog.d(TAG, "Asked to create backup agent for nonexistent package"); 3197 return; 3198 } 3199 3200 String classname = data.appInfo.backupAgentName; 3201 // full backup operation but no app-supplied agent? use the default implementation 3202 if (classname == null && (data.backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL 3203 || data.backupMode == ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL)) { 3204 classname = "android.app.backup.FullBackupAgent"; 3205 } 3206 3207 try { 3208 IBinder binder = null; 3209 BackupAgent agent = mBackupAgents.get(packageName); 3210 if (agent != null) { 3211 // reusing the existing instance 3212 if (DEBUG_BACKUP) { 3213 Slog.v(TAG, "Reusing existing agent instance"); 3214 } 3215 binder = agent.onBind(); 3216 } else { 3217 try { 3218 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname); 3219 3220 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 3221 agent = (BackupAgent) cl.loadClass(classname).newInstance(); 3222 3223 // set up the agent's context 3224 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 3225 context.setOuterContext(agent); 3226 agent.attach(context); 3227 3228 agent.onCreate(); 3229 binder = agent.onBind(); 3230 mBackupAgents.put(packageName, agent); 3231 } catch (Exception e) { 3232 // If this is during restore, fail silently; otherwise go 3233 // ahead and let the user see the crash. 3234 Slog.e(TAG, "Agent threw during creation: " + e); 3235 if (data.backupMode != ApplicationThreadConstants.BACKUP_MODE_RESTORE 3236 && data.backupMode != 3237 ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL) { 3238 throw e; 3239 } 3240 // falling through with 'binder' still null 3241 } 3242 } 3243 3244 // tell the OS that we're live now 3245 try { 3246 ActivityManager.getService().backupAgentCreated(packageName, binder); 3247 } catch (RemoteException e) { 3248 throw e.rethrowFromSystemServer(); 3249 } 3250 } catch (Exception e) { 3251 throw new RuntimeException("Unable to create BackupAgent " 3252 + classname + ": " + e.toString(), e); 3253 } 3254 } 3255 3256 // Tear down a BackupAgent 3257 private void handleDestroyBackupAgent(CreateBackupAgentData data) { 3258 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data); 3259 3260 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 3261 String packageName = packageInfo.mPackageName; 3262 BackupAgent agent = mBackupAgents.get(packageName); 3263 if (agent != null) { 3264 try { 3265 agent.onDestroy(); 3266 } catch (Exception e) { 3267 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo); 3268 e.printStackTrace(); 3269 } 3270 mBackupAgents.remove(packageName); 3271 } else { 3272 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data); 3273 } 3274 } 3275 3276 private void handleCreateService(CreateServiceData data) { 3277 // If we are getting ready to gc after going to the background, well 3278 // we are back active so skip it. 3279 unscheduleGcIdler(); 3280 3281 LoadedApk packageInfo = getPackageInfoNoCheck( 3282 data.info.applicationInfo, data.compatInfo); 3283 Service service = null; 3284 try { 3285 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 3286 service = (Service) cl.loadClass(data.info.name).newInstance(); 3287 } catch (Exception e) { 3288 if (!mInstrumentation.onException(service, e)) { 3289 throw new RuntimeException( 3290 "Unable to instantiate service " + data.info.name 3291 + ": " + e.toString(), e); 3292 } 3293 } 3294 3295 try { 3296 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 3297 3298 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 3299 context.setOuterContext(service); 3300 3301 Application app = packageInfo.makeApplication(false, mInstrumentation); 3302 service.attach(context, this, data.info.name, data.token, app, 3303 ActivityManager.getService()); 3304 service.onCreate(); 3305 mServices.put(data.token, service); 3306 try { 3307 ActivityManager.getService().serviceDoneExecuting( 3308 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3309 } catch (RemoteException e) { 3310 throw e.rethrowFromSystemServer(); 3311 } 3312 } catch (Exception e) { 3313 if (!mInstrumentation.onException(service, e)) { 3314 throw new RuntimeException( 3315 "Unable to create service " + data.info.name 3316 + ": " + e.toString(), e); 3317 } 3318 } 3319 } 3320 3321 private void handleBindService(BindServiceData data) { 3322 Service s = mServices.get(data.token); 3323 if (DEBUG_SERVICE) 3324 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); 3325 if (s != null) { 3326 try { 3327 data.intent.setExtrasClassLoader(s.getClassLoader()); 3328 data.intent.prepareToEnterProcess(); 3329 try { 3330 if (!data.rebind) { 3331 IBinder binder = s.onBind(data.intent); 3332 ActivityManager.getService().publishService( 3333 data.token, data.intent, binder); 3334 } else { 3335 s.onRebind(data.intent); 3336 ActivityManager.getService().serviceDoneExecuting( 3337 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3338 } 3339 ensureJitEnabled(); 3340 } catch (RemoteException ex) { 3341 throw ex.rethrowFromSystemServer(); 3342 } 3343 } catch (Exception e) { 3344 if (!mInstrumentation.onException(s, e)) { 3345 throw new RuntimeException( 3346 "Unable to bind to service " + s 3347 + " with " + data.intent + ": " + e.toString(), e); 3348 } 3349 } 3350 } 3351 } 3352 3353 private void handleUnbindService(BindServiceData data) { 3354 Service s = mServices.get(data.token); 3355 if (s != null) { 3356 try { 3357 data.intent.setExtrasClassLoader(s.getClassLoader()); 3358 data.intent.prepareToEnterProcess(); 3359 boolean doRebind = s.onUnbind(data.intent); 3360 try { 3361 if (doRebind) { 3362 ActivityManager.getService().unbindFinished( 3363 data.token, data.intent, doRebind); 3364 } else { 3365 ActivityManager.getService().serviceDoneExecuting( 3366 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3367 } 3368 } catch (RemoteException ex) { 3369 throw ex.rethrowFromSystemServer(); 3370 } 3371 } catch (Exception e) { 3372 if (!mInstrumentation.onException(s, e)) { 3373 throw new RuntimeException( 3374 "Unable to unbind to service " + s 3375 + " with " + data.intent + ": " + e.toString(), e); 3376 } 3377 } 3378 } 3379 } 3380 3381 private void handleDumpService(DumpComponentInfo info) { 3382 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3383 try { 3384 Service s = mServices.get(info.token); 3385 if (s != null) { 3386 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 3387 info.fd.getFileDescriptor())); 3388 s.dump(info.fd.getFileDescriptor(), pw, info.args); 3389 pw.flush(); 3390 } 3391 } finally { 3392 IoUtils.closeQuietly(info.fd); 3393 StrictMode.setThreadPolicy(oldPolicy); 3394 } 3395 } 3396 3397 private void handleDumpActivity(DumpComponentInfo info) { 3398 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3399 try { 3400 ActivityClientRecord r = mActivities.get(info.token); 3401 if (r != null && r.activity != null) { 3402 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 3403 info.fd.getFileDescriptor())); 3404 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); 3405 pw.flush(); 3406 } 3407 } finally { 3408 IoUtils.closeQuietly(info.fd); 3409 StrictMode.setThreadPolicy(oldPolicy); 3410 } 3411 } 3412 3413 private void handleDumpProvider(DumpComponentInfo info) { 3414 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3415 try { 3416 ProviderClientRecord r = mLocalProviders.get(info.token); 3417 if (r != null && r.mLocalProvider != null) { 3418 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 3419 info.fd.getFileDescriptor())); 3420 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args); 3421 pw.flush(); 3422 } 3423 } finally { 3424 IoUtils.closeQuietly(info.fd); 3425 StrictMode.setThreadPolicy(oldPolicy); 3426 } 3427 } 3428 3429 private void handleServiceArgs(ServiceArgsData data) { 3430 Service s = mServices.get(data.token); 3431 if (s != null) { 3432 try { 3433 if (data.args != null) { 3434 data.args.setExtrasClassLoader(s.getClassLoader()); 3435 data.args.prepareToEnterProcess(); 3436 } 3437 int res; 3438 if (!data.taskRemoved) { 3439 res = s.onStartCommand(data.args, data.flags, data.startId); 3440 } else { 3441 s.onTaskRemoved(data.args); 3442 res = Service.START_TASK_REMOVED_COMPLETE; 3443 } 3444 3445 QueuedWork.waitToFinish(); 3446 3447 try { 3448 ActivityManager.getService().serviceDoneExecuting( 3449 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); 3450 } catch (RemoteException e) { 3451 throw e.rethrowFromSystemServer(); 3452 } 3453 ensureJitEnabled(); 3454 } catch (Exception e) { 3455 if (!mInstrumentation.onException(s, e)) { 3456 throw new RuntimeException( 3457 "Unable to start service " + s 3458 + " with " + data.args + ": " + e.toString(), e); 3459 } 3460 } 3461 } 3462 } 3463 3464 private void handleStopService(IBinder token) { 3465 Service s = mServices.remove(token); 3466 if (s != null) { 3467 try { 3468 if (localLOGV) Slog.v(TAG, "Destroying service " + s); 3469 s.onDestroy(); 3470 Context context = s.getBaseContext(); 3471 if (context instanceof ContextImpl) { 3472 final String who = s.getClassName(); 3473 ((ContextImpl) context).scheduleFinalCleanup(who, "Service"); 3474 } 3475 3476 QueuedWork.waitToFinish(); 3477 3478 try { 3479 ActivityManager.getService().serviceDoneExecuting( 3480 token, SERVICE_DONE_EXECUTING_STOP, 0, 0); 3481 } catch (RemoteException e) { 3482 throw e.rethrowFromSystemServer(); 3483 } 3484 } catch (Exception e) { 3485 if (!mInstrumentation.onException(s, e)) { 3486 throw new RuntimeException( 3487 "Unable to stop service " + s 3488 + ": " + e.toString(), e); 3489 } 3490 Slog.i(TAG, "handleStopService: exception for " + token, e); 3491 } 3492 } else { 3493 Slog.i(TAG, "handleStopService: token=" + token + " not found."); 3494 } 3495 //Slog.i(TAG, "Running services: " + mServices); 3496 } 3497 3498 public final ActivityClientRecord performResumeActivity(IBinder token, 3499 boolean clearHide, String reason) { 3500 ActivityClientRecord r = mActivities.get(token); 3501 if (localLOGV) Slog.v(TAG, "Performing resume of " + r 3502 + " finished=" + r.activity.mFinished); 3503 if (r != null && !r.activity.mFinished) { 3504 if (clearHide) { 3505 r.hideForNow = false; 3506 r.activity.mStartedActivity = false; 3507 } 3508 try { 3509 r.activity.onStateNotSaved(); 3510 r.activity.mFragments.noteStateNotSaved(); 3511 if (r.pendingIntents != null) { 3512 deliverNewIntents(r, r.pendingIntents); 3513 r.pendingIntents = null; 3514 } 3515 if (r.pendingResults != null) { 3516 deliverResults(r, r.pendingResults); 3517 r.pendingResults = null; 3518 } 3519 r.activity.performResume(); 3520 3521 synchronized (mResourcesManager) { 3522 // If there is a pending local relaunch that was requested when the activity was 3523 // paused, it will put the activity into paused state when it finally happens. 3524 // Since the activity resumed before being relaunched, we don't want that to 3525 // happen, so we need to clear the request to relaunch paused. 3526 for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) { 3527 final ActivityClientRecord relaunching = mRelaunchingActivities.get(i); 3528 if (relaunching.token == r.token 3529 && relaunching.onlyLocalRequest && relaunching.startsNotResumed) { 3530 relaunching.startsNotResumed = false; 3531 } 3532 } 3533 } 3534 3535 EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(), 3536 r.activity.getComponentName().getClassName(), reason); 3537 3538 r.paused = false; 3539 r.stopped = false; 3540 r.state = null; 3541 r.persistentState = null; 3542 } catch (Exception e) { 3543 if (!mInstrumentation.onException(r.activity, e)) { 3544 throw new RuntimeException( 3545 "Unable to resume activity " 3546 + r.intent.getComponent().toShortString() 3547 + ": " + e.toString(), e); 3548 } 3549 } 3550 } 3551 return r; 3552 } 3553 3554 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) { 3555 if (r.mPreserveWindow && !force) { 3556 return; 3557 } 3558 if (r.mPendingRemoveWindow != null) { 3559 r.mPendingRemoveWindowManager.removeViewImmediate( 3560 r.mPendingRemoveWindow.getDecorView()); 3561 IBinder wtoken = r.mPendingRemoveWindow.getDecorView().getWindowToken(); 3562 if (wtoken != null) { 3563 WindowManagerGlobal.getInstance().closeAll(wtoken, 3564 r.activity.getClass().getName(), "Activity"); 3565 } 3566 } 3567 r.mPendingRemoveWindow = null; 3568 r.mPendingRemoveWindowManager = null; 3569 } 3570 3571 final void handleResumeActivity(IBinder token, 3572 boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) { 3573 ActivityClientRecord r = mActivities.get(token); 3574 if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) { 3575 return; 3576 } 3577 3578 // If we are getting ready to gc after going to the background, well 3579 // we are back active so skip it. 3580 unscheduleGcIdler(); 3581 mSomeActivitiesChanged = true; 3582 3583 // TODO Push resumeArgs into the activity for consideration 3584 r = performResumeActivity(token, clearHide, reason); 3585 3586 if (r != null) { 3587 final Activity a = r.activity; 3588 3589 if (localLOGV) Slog.v( 3590 TAG, "Resume " + r + " started activity: " + 3591 a.mStartedActivity + ", hideForNow: " + r.hideForNow 3592 + ", finished: " + a.mFinished); 3593 3594 final int forwardBit = isForward ? 3595 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 3596 3597 // If the window hasn't yet been added to the window manager, 3598 // and this guy didn't finish itself or start another activity, 3599 // then go ahead and add the window. 3600 boolean willBeVisible = !a.mStartedActivity; 3601 if (!willBeVisible) { 3602 try { 3603 willBeVisible = ActivityManager.getService().willActivityBeVisible( 3604 a.getActivityToken()); 3605 } catch (RemoteException e) { 3606 throw e.rethrowFromSystemServer(); 3607 } 3608 } 3609 if (r.window == null && !a.mFinished && willBeVisible) { 3610 r.window = r.activity.getWindow(); 3611 View decor = r.window.getDecorView(); 3612 decor.setVisibility(View.INVISIBLE); 3613 ViewManager wm = a.getWindowManager(); 3614 WindowManager.LayoutParams l = r.window.getAttributes(); 3615 a.mDecor = decor; 3616 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 3617 l.softInputMode |= forwardBit; 3618 if (r.mPreserveWindow) { 3619 a.mWindowAdded = true; 3620 r.mPreserveWindow = false; 3621 // Normally the ViewRoot sets up callbacks with the Activity 3622 // in addView->ViewRootImpl#setView. If we are instead reusing 3623 // the decor view we have to notify the view root that the 3624 // callbacks may have changed. 3625 ViewRootImpl impl = decor.getViewRootImpl(); 3626 if (impl != null) { 3627 impl.notifyChildRebuilt(); 3628 } 3629 } 3630 if (a.mVisibleFromClient && !a.mWindowAdded) { 3631 a.mWindowAdded = true; 3632 wm.addView(decor, l); 3633 } 3634 3635 // If the window has already been added, but during resume 3636 // we started another activity, then don't yet make the 3637 // window visible. 3638 } else if (!willBeVisible) { 3639 if (localLOGV) Slog.v( 3640 TAG, "Launch " + r + " mStartedActivity set"); 3641 r.hideForNow = true; 3642 } 3643 3644 // Get rid of anything left hanging around. 3645 cleanUpPendingRemoveWindows(r, false /* force */); 3646 3647 // The window is now visible if it has been added, we are not 3648 // simply finishing, and we are not starting another activity. 3649 if (!r.activity.mFinished && willBeVisible 3650 && r.activity.mDecor != null && !r.hideForNow) { 3651 if (r.newConfig != null) { 3652 performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY); 3653 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 3654 + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig); 3655 r.newConfig = null; 3656 } 3657 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 3658 + isForward); 3659 WindowManager.LayoutParams l = r.window.getAttributes(); 3660 if ((l.softInputMode 3661 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 3662 != forwardBit) { 3663 l.softInputMode = (l.softInputMode 3664 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 3665 | forwardBit; 3666 if (r.activity.mVisibleFromClient) { 3667 ViewManager wm = a.getWindowManager(); 3668 View decor = r.window.getDecorView(); 3669 wm.updateViewLayout(decor, l); 3670 } 3671 } 3672 r.activity.mVisibleFromServer = true; 3673 mNumVisibleActivities++; 3674 if (r.activity.mVisibleFromClient) { 3675 r.activity.makeVisible(); 3676 } 3677 } 3678 3679 if (!r.onlyLocalRequest) { 3680 r.nextIdle = mNewActivities; 3681 mNewActivities = r; 3682 if (localLOGV) Slog.v( 3683 TAG, "Scheduling idle handler for " + r); 3684 Looper.myQueue().addIdleHandler(new Idler()); 3685 } 3686 r.onlyLocalRequest = false; 3687 3688 // Tell the activity manager we have resumed. 3689 if (reallyResume) { 3690 try { 3691 ActivityManager.getService().activityResumed(token); 3692 } catch (RemoteException ex) { 3693 throw ex.rethrowFromSystemServer(); 3694 } 3695 } 3696 3697 } else { 3698 // If an exception was thrown when trying to resume, then 3699 // just end this activity. 3700 try { 3701 ActivityManager.getService() 3702 .finishActivity(token, Activity.RESULT_CANCELED, null, 3703 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 3704 } catch (RemoteException ex) { 3705 throw ex.rethrowFromSystemServer(); 3706 } 3707 } 3708 } 3709 3710 private int mThumbnailWidth = -1; 3711 private int mThumbnailHeight = -1; 3712 private Bitmap mAvailThumbnailBitmap = null; 3713 private Canvas mThumbnailCanvas = null; 3714 3715 private Bitmap createThumbnailBitmap(ActivityClientRecord r) { 3716 Bitmap thumbnail = mAvailThumbnailBitmap; 3717 try { 3718 if (thumbnail == null) { 3719 int w = mThumbnailWidth; 3720 int h; 3721 if (w < 0) { 3722 Resources res = r.activity.getResources(); 3723 int wId = com.android.internal.R.dimen.thumbnail_width; 3724 int hId = com.android.internal.R.dimen.thumbnail_height; 3725 mThumbnailWidth = w = res.getDimensionPixelSize(wId); 3726 mThumbnailHeight = h = res.getDimensionPixelSize(hId); 3727 } else { 3728 h = mThumbnailHeight; 3729 } 3730 3731 // On platforms where we don't want thumbnails, set dims to (0,0) 3732 if ((w > 0) && (h > 0)) { 3733 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 3734 w, h, THUMBNAIL_FORMAT); 3735 thumbnail.eraseColor(0); 3736 } 3737 } 3738 3739 if (thumbnail != null) { 3740 Canvas cv = mThumbnailCanvas; 3741 if (cv == null) { 3742 mThumbnailCanvas = cv = new Canvas(); 3743 } 3744 3745 cv.setBitmap(thumbnail); 3746 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 3747 mAvailThumbnailBitmap = thumbnail; 3748 thumbnail = null; 3749 } 3750 cv.setBitmap(null); 3751 } 3752 3753 } catch (Exception e) { 3754 if (!mInstrumentation.onException(r.activity, e)) { 3755 throw new RuntimeException( 3756 "Unable to create thumbnail of " 3757 + r.intent.getComponent().toShortString() 3758 + ": " + e.toString(), e); 3759 } 3760 thumbnail = null; 3761 } 3762 3763 return thumbnail; 3764 } 3765 3766 private void handlePauseActivity(IBinder token, boolean finished, 3767 boolean userLeaving, int configChanges, boolean dontReport, int seq) { 3768 ActivityClientRecord r = mActivities.get(token); 3769 if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq); 3770 if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) { 3771 return; 3772 } 3773 if (r != null) { 3774 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 3775 if (userLeaving) { 3776 performUserLeavingActivity(r); 3777 } 3778 3779 r.activity.mConfigChangeFlags |= configChanges; 3780 performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity"); 3781 3782 // Make sure any pending writes are now committed. 3783 if (r.isPreHoneycomb()) { 3784 QueuedWork.waitToFinish(); 3785 } 3786 3787 // Tell the activity manager we have paused. 3788 if (!dontReport) { 3789 try { 3790 ActivityManager.getService().activityPaused(token); 3791 } catch (RemoteException ex) { 3792 throw ex.rethrowFromSystemServer(); 3793 } 3794 } 3795 mSomeActivitiesChanged = true; 3796 } 3797 } 3798 3799 final void performUserLeavingActivity(ActivityClientRecord r) { 3800 mInstrumentation.callActivityOnUserLeaving(r.activity); 3801 } 3802 3803 final Bundle performPauseActivity(IBinder token, boolean finished, 3804 boolean saveState, String reason) { 3805 ActivityClientRecord r = mActivities.get(token); 3806 return r != null ? performPauseActivity(r, finished, saveState, reason) : null; 3807 } 3808 3809 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 3810 boolean saveState, String reason) { 3811 if (r.paused) { 3812 if (r.activity.mFinished) { 3813 // If we are finishing, we won't call onResume() in certain cases. 3814 // So here we likewise don't want to call onPause() if the activity 3815 // isn't resumed. 3816 return null; 3817 } 3818 RuntimeException e = new RuntimeException( 3819 "Performing pause of activity that is not resumed: " 3820 + r.intent.getComponent().toShortString()); 3821 Slog.e(TAG, e.getMessage(), e); 3822 } 3823 if (finished) { 3824 r.activity.mFinished = true; 3825 } 3826 3827 // Next have the activity save its current state and managed dialogs... 3828 if (!r.activity.mFinished && saveState) { 3829 callCallActivityOnSaveInstanceState(r); 3830 } 3831 3832 performPauseActivityIfNeeded(r, reason); 3833 3834 // Notify any outstanding on paused listeners 3835 ArrayList<OnActivityPausedListener> listeners; 3836 synchronized (mOnPauseListeners) { 3837 listeners = mOnPauseListeners.remove(r.activity); 3838 } 3839 int size = (listeners != null ? listeners.size() : 0); 3840 for (int i = 0; i < size; i++) { 3841 listeners.get(i).onPaused(r.activity); 3842 } 3843 3844 return !r.activity.mFinished && saveState ? r.state : null; 3845 } 3846 3847 private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) { 3848 if (r.paused) { 3849 // You are already paused silly... 3850 return; 3851 } 3852 3853 try { 3854 r.activity.mCalled = false; 3855 mInstrumentation.callActivityOnPause(r.activity); 3856 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), 3857 r.activity.getComponentName().getClassName(), reason); 3858 if (!r.activity.mCalled) { 3859 throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent) 3860 + " did not call through to super.onPause()"); 3861 } 3862 } catch (SuperNotCalledException e) { 3863 throw e; 3864 } catch (Exception e) { 3865 if (!mInstrumentation.onException(r.activity, e)) { 3866 throw new RuntimeException("Unable to pause activity " 3867 + safeToComponentShortString(r.intent) + ": " + e.toString(), e); 3868 } 3869 } 3870 r.paused = true; 3871 } 3872 3873 final void performStopActivity(IBinder token, boolean saveState, String reason) { 3874 ActivityClientRecord r = mActivities.get(token); 3875 performStopActivityInner(r, null, false, saveState, reason); 3876 } 3877 3878 private static class StopInfo implements Runnable { 3879 ActivityClientRecord activity; 3880 Bundle state; 3881 PersistableBundle persistentState; 3882 CharSequence description; 3883 3884 @Override public void run() { 3885 // Tell activity manager we have been stopped. 3886 try { 3887 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3888 ActivityManager.getService().activityStopped( 3889 activity.token, state, persistentState, description); 3890 } catch (RemoteException ex) { 3891 if (ex instanceof TransactionTooLargeException 3892 && activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) { 3893 Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex); 3894 return; 3895 } 3896 throw ex.rethrowFromSystemServer(); 3897 } 3898 } 3899 } 3900 3901 private static final class ProviderRefCount { 3902 public final ContentProviderHolder holder; 3903 public final ProviderClientRecord client; 3904 public int stableCount; 3905 public int unstableCount; 3906 3907 // When this is set, the stable and unstable ref counts are 0 and 3908 // we have a pending operation scheduled to remove the ref count 3909 // from the activity manager. On the activity manager we are still 3910 // holding an unstable ref, though it is not reflected in the counts 3911 // here. 3912 public boolean removePending; 3913 3914 ProviderRefCount(ContentProviderHolder inHolder, 3915 ProviderClientRecord inClient, int sCount, int uCount) { 3916 holder = inHolder; 3917 client = inClient; 3918 stableCount = sCount; 3919 unstableCount = uCount; 3920 } 3921 } 3922 3923 /** 3924 * Core implementation of stopping an activity. Note this is a little 3925 * tricky because the server's meaning of stop is slightly different 3926 * than our client -- for the server, stop means to save state and give 3927 * it the result when it is done, but the window may still be visible. 3928 * For the client, we want to call onStop()/onStart() to indicate when 3929 * the activity's UI visibility changes. 3930 */ 3931 private void performStopActivityInner(ActivityClientRecord r, 3932 StopInfo info, boolean keepShown, boolean saveState, String reason) { 3933 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3934 if (r != null) { 3935 if (!keepShown && r.stopped) { 3936 if (r.activity.mFinished) { 3937 // If we are finishing, we won't call onResume() in certain 3938 // cases. So here we likewise don't want to call onStop() 3939 // if the activity isn't resumed. 3940 return; 3941 } 3942 RuntimeException e = new RuntimeException( 3943 "Performing stop of activity that is already stopped: " 3944 + r.intent.getComponent().toShortString()); 3945 Slog.e(TAG, e.getMessage(), e); 3946 Slog.e(TAG, r.getStateString()); 3947 } 3948 3949 // One must first be paused before stopped... 3950 performPauseActivityIfNeeded(r, reason); 3951 3952 if (info != null) { 3953 try { 3954 // First create a thumbnail for the activity... 3955 // For now, don't create the thumbnail here; we are 3956 // doing that by doing a screen snapshot. 3957 info.description = r.activity.onCreateDescription(); 3958 } catch (Exception e) { 3959 if (!mInstrumentation.onException(r.activity, e)) { 3960 throw new RuntimeException( 3961 "Unable to save state of activity " 3962 + r.intent.getComponent().toShortString() 3963 + ": " + e.toString(), e); 3964 } 3965 } 3966 } 3967 3968 // Next have the activity save its current state and managed dialogs... 3969 if (!r.activity.mFinished && saveState) { 3970 if (r.state == null) { 3971 callCallActivityOnSaveInstanceState(r); 3972 } 3973 } 3974 3975 if (!keepShown) { 3976 try { 3977 // Now we are idle. 3978 r.activity.performStop(false /*preserveWindow*/); 3979 } catch (Exception e) { 3980 if (!mInstrumentation.onException(r.activity, e)) { 3981 throw new RuntimeException( 3982 "Unable to stop activity " 3983 + r.intent.getComponent().toShortString() 3984 + ": " + e.toString(), e); 3985 } 3986 } 3987 r.stopped = true; 3988 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(), 3989 r.activity.getComponentName().getClassName(), reason); 3990 } 3991 } 3992 } 3993 3994 private void updateVisibility(ActivityClientRecord r, boolean show) { 3995 View v = r.activity.mDecor; 3996 if (v != null) { 3997 if (show) { 3998 if (!r.activity.mVisibleFromServer) { 3999 r.activity.mVisibleFromServer = true; 4000 mNumVisibleActivities++; 4001 if (r.activity.mVisibleFromClient) { 4002 r.activity.makeVisible(); 4003 } 4004 } 4005 if (r.newConfig != null) { 4006 performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY); 4007 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 4008 + r.activityInfo.name + " with new config " 4009 + r.activity.mCurrentConfig); 4010 r.newConfig = null; 4011 } 4012 } else { 4013 if (r.activity.mVisibleFromServer) { 4014 r.activity.mVisibleFromServer = false; 4015 mNumVisibleActivities--; 4016 v.setVisibility(View.INVISIBLE); 4017 } 4018 } 4019 } 4020 } 4021 4022 private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) { 4023 ActivityClientRecord r = mActivities.get(token); 4024 if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) { 4025 return; 4026 } 4027 r.activity.mConfigChangeFlags |= configChanges; 4028 4029 StopInfo info = new StopInfo(); 4030 performStopActivityInner(r, info, show, true, "handleStopActivity"); 4031 4032 if (localLOGV) Slog.v( 4033 TAG, "Finishing stop of " + r + ": show=" + show 4034 + " win=" + r.window); 4035 4036 updateVisibility(r, show); 4037 4038 // Make sure any pending writes are now committed. 4039 if (!r.isPreHoneycomb()) { 4040 QueuedWork.waitToFinish(); 4041 } 4042 4043 // Schedule the call to tell the activity manager we have 4044 // stopped. We don't do this immediately, because we want to 4045 // have a chance for any other pending work (in particular memory 4046 // trim requests) to complete before you tell the activity 4047 // manager to proceed and allow us to go fully into the background. 4048 info.activity = r; 4049 info.state = r.state; 4050 info.persistentState = r.persistentState; 4051 mH.post(info); 4052 mSomeActivitiesChanged = true; 4053 } 4054 4055 private static boolean checkAndUpdateLifecycleSeq(int seq, ActivityClientRecord r, 4056 String action) { 4057 if (r == null) { 4058 return true; 4059 } 4060 if (seq < r.lastProcessedSeq) { 4061 if (DEBUG_ORDER) Slog.d(TAG, action + " for " + r + " ignored, because seq=" + seq 4062 + " < mCurrentLifecycleSeq=" + r.lastProcessedSeq); 4063 return false; 4064 } 4065 r.lastProcessedSeq = seq; 4066 return true; 4067 } 4068 4069 final void performRestartActivity(IBinder token) { 4070 ActivityClientRecord r = mActivities.get(token); 4071 if (r.stopped) { 4072 r.activity.performRestart(); 4073 r.stopped = false; 4074 } 4075 } 4076 4077 private void handleWindowVisibility(IBinder token, boolean show) { 4078 ActivityClientRecord r = mActivities.get(token); 4079 4080 if (r == null) { 4081 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 4082 return; 4083 } 4084 4085 if (!show && !r.stopped) { 4086 performStopActivityInner(r, null, show, false, "handleWindowVisibility"); 4087 } else if (show && r.stopped) { 4088 // If we are getting ready to gc after going to the background, well 4089 // we are back active so skip it. 4090 unscheduleGcIdler(); 4091 4092 r.activity.performRestart(); 4093 r.stopped = false; 4094 } 4095 if (r.activity.mDecor != null) { 4096 if (false) Slog.v( 4097 TAG, "Handle window " + r + " visibility: " + show); 4098 updateVisibility(r, show); 4099 } 4100 mSomeActivitiesChanged = true; 4101 } 4102 4103 // TODO: This method should be changed to use {@link #performStopActivityInner} to perform to 4104 // stop operation on the activity to reduce code duplication and the chance of fixing a bug in 4105 // one place and missing the other. 4106 private void handleSleeping(IBinder token, boolean sleeping) { 4107 ActivityClientRecord r = mActivities.get(token); 4108 4109 if (r == null) { 4110 Log.w(TAG, "handleSleeping: no activity for token " + token); 4111 return; 4112 } 4113 4114 if (sleeping) { 4115 if (!r.stopped && !r.isPreHoneycomb()) { 4116 if (!r.activity.mFinished && r.state == null) { 4117 callCallActivityOnSaveInstanceState(r); 4118 } 4119 4120 try { 4121 // Now we are idle. 4122 r.activity.performStop(false /*preserveWindow*/); 4123 } catch (Exception e) { 4124 if (!mInstrumentation.onException(r.activity, e)) { 4125 throw new RuntimeException( 4126 "Unable to stop activity " 4127 + r.intent.getComponent().toShortString() 4128 + ": " + e.toString(), e); 4129 } 4130 } 4131 r.stopped = true; 4132 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(), 4133 r.activity.getComponentName().getClassName(), "sleeping"); 4134 } 4135 4136 // Make sure any pending writes are now committed. 4137 if (!r.isPreHoneycomb()) { 4138 QueuedWork.waitToFinish(); 4139 } 4140 4141 // Tell activity manager we slept. 4142 try { 4143 ActivityManager.getService().activitySlept(r.token); 4144 } catch (RemoteException ex) { 4145 throw ex.rethrowFromSystemServer(); 4146 } 4147 } else { 4148 if (r.stopped && r.activity.mVisibleFromServer) { 4149 r.activity.performRestart(); 4150 r.stopped = false; 4151 } 4152 } 4153 } 4154 4155 private void handleSetCoreSettings(Bundle coreSettings) { 4156 synchronized (mResourcesManager) { 4157 mCoreSettings = coreSettings; 4158 } 4159 onCoreSettingsChange(); 4160 } 4161 4162 private void onCoreSettingsChange() { 4163 boolean debugViewAttributes = 4164 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 4165 if (debugViewAttributes != View.mDebugViewAttributes) { 4166 View.mDebugViewAttributes = debugViewAttributes; 4167 4168 // request all activities to relaunch for the changes to take place 4169 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { 4170 requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false, 4171 false /* preserveWindow */); 4172 } 4173 } 4174 } 4175 4176 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 4177 LoadedApk apk = peekPackageInfo(data.pkg, false); 4178 if (apk != null) { 4179 apk.setCompatibilityInfo(data.info); 4180 } 4181 apk = peekPackageInfo(data.pkg, true); 4182 if (apk != null) { 4183 apk.setCompatibilityInfo(data.info); 4184 } 4185 handleConfigurationChanged(mConfiguration, data.info); 4186 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 4187 } 4188 4189 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 4190 final int N = results.size(); 4191 for (int i=0; i<N; i++) { 4192 ResultInfo ri = results.get(i); 4193 try { 4194 if (ri.mData != null) { 4195 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 4196 ri.mData.prepareToEnterProcess(); 4197 } 4198 if (DEBUG_RESULTS) Slog.v(TAG, 4199 "Delivering result to activity " + r + " : " + ri); 4200 r.activity.dispatchActivityResult(ri.mResultWho, 4201 ri.mRequestCode, ri.mResultCode, ri.mData); 4202 } catch (Exception e) { 4203 if (!mInstrumentation.onException(r.activity, e)) { 4204 throw new RuntimeException( 4205 "Failure delivering result " + ri + " to activity " 4206 + r.intent.getComponent().toShortString() 4207 + ": " + e.toString(), e); 4208 } 4209 } 4210 } 4211 } 4212 4213 private void handleSendResult(ResultData res) { 4214 ActivityClientRecord r = mActivities.get(res.token); 4215 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 4216 if (r != null) { 4217 final boolean resumed = !r.paused; 4218 if (!r.activity.mFinished && r.activity.mDecor != null 4219 && r.hideForNow && resumed) { 4220 // We had hidden the activity because it started another 4221 // one... we have gotten a result back and we are not 4222 // paused, so make sure our window is visible. 4223 updateVisibility(r, true); 4224 } 4225 if (resumed) { 4226 try { 4227 // Now we are idle. 4228 r.activity.mCalled = false; 4229 r.activity.mTemporaryPause = true; 4230 mInstrumentation.callActivityOnPause(r.activity); 4231 if (!r.activity.mCalled) { 4232 throw new SuperNotCalledException( 4233 "Activity " + r.intent.getComponent().toShortString() 4234 + " did not call through to super.onPause()"); 4235 } 4236 } catch (SuperNotCalledException e) { 4237 throw e; 4238 } catch (Exception e) { 4239 if (!mInstrumentation.onException(r.activity, e)) { 4240 throw new RuntimeException( 4241 "Unable to pause activity " 4242 + r.intent.getComponent().toShortString() 4243 + ": " + e.toString(), e); 4244 } 4245 } 4246 } 4247 deliverResults(r, res.results); 4248 if (resumed) { 4249 r.activity.performResume(); 4250 r.activity.mTemporaryPause = false; 4251 } 4252 } 4253 } 4254 4255 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 4256 return performDestroyActivity(token, finishing, 0, false); 4257 } 4258 4259 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 4260 int configChanges, boolean getNonConfigInstance) { 4261 ActivityClientRecord r = mActivities.get(token); 4262 Class<? extends Activity> activityClass = null; 4263 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 4264 if (r != null) { 4265 activityClass = r.activity.getClass(); 4266 r.activity.mConfigChangeFlags |= configChanges; 4267 if (finishing) { 4268 r.activity.mFinished = true; 4269 } 4270 4271 performPauseActivityIfNeeded(r, "destroy"); 4272 4273 if (!r.stopped) { 4274 try { 4275 r.activity.performStop(r.mPreserveWindow); 4276 } catch (SuperNotCalledException e) { 4277 throw e; 4278 } catch (Exception e) { 4279 if (!mInstrumentation.onException(r.activity, e)) { 4280 throw new RuntimeException( 4281 "Unable to stop activity " 4282 + safeToComponentShortString(r.intent) 4283 + ": " + e.toString(), e); 4284 } 4285 } 4286 r.stopped = true; 4287 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(), 4288 r.activity.getComponentName().getClassName(), "destroy"); 4289 } 4290 if (getNonConfigInstance) { 4291 try { 4292 r.lastNonConfigurationInstances 4293 = r.activity.retainNonConfigurationInstances(); 4294 } catch (Exception e) { 4295 if (!mInstrumentation.onException(r.activity, e)) { 4296 throw new RuntimeException( 4297 "Unable to retain activity " 4298 + r.intent.getComponent().toShortString() 4299 + ": " + e.toString(), e); 4300 } 4301 } 4302 } 4303 try { 4304 r.activity.mCalled = false; 4305 mInstrumentation.callActivityOnDestroy(r.activity); 4306 if (!r.activity.mCalled) { 4307 throw new SuperNotCalledException( 4308 "Activity " + safeToComponentShortString(r.intent) + 4309 " did not call through to super.onDestroy()"); 4310 } 4311 if (r.window != null) { 4312 r.window.closeAllPanels(); 4313 } 4314 } catch (SuperNotCalledException e) { 4315 throw e; 4316 } catch (Exception e) { 4317 if (!mInstrumentation.onException(r.activity, e)) { 4318 throw new RuntimeException( 4319 "Unable to destroy activity " + safeToComponentShortString(r.intent) 4320 + ": " + e.toString(), e); 4321 } 4322 } 4323 } 4324 mActivities.remove(token); 4325 StrictMode.decrementExpectedActivityCount(activityClass); 4326 return r; 4327 } 4328 4329 private static String safeToComponentShortString(Intent intent) { 4330 ComponentName component = intent.getComponent(); 4331 return component == null ? "[Unknown]" : component.toShortString(); 4332 } 4333 4334 private void handleDestroyActivity(IBinder token, boolean finishing, 4335 int configChanges, boolean getNonConfigInstance) { 4336 ActivityClientRecord r = performDestroyActivity(token, finishing, 4337 configChanges, getNonConfigInstance); 4338 if (r != null) { 4339 cleanUpPendingRemoveWindows(r, finishing); 4340 WindowManager wm = r.activity.getWindowManager(); 4341 View v = r.activity.mDecor; 4342 if (v != null) { 4343 if (r.activity.mVisibleFromServer) { 4344 mNumVisibleActivities--; 4345 } 4346 IBinder wtoken = v.getWindowToken(); 4347 if (r.activity.mWindowAdded) { 4348 if (r.mPreserveWindow) { 4349 // Hold off on removing this until the new activity's 4350 // window is being added. 4351 r.mPendingRemoveWindow = r.window; 4352 r.mPendingRemoveWindowManager = wm; 4353 // We can only keep the part of the view hierarchy that we control, 4354 // everything else must be removed, because it might not be able to 4355 // behave properly when activity is relaunching. 4356 r.window.clearContentView(); 4357 } else { 4358 wm.removeViewImmediate(v); 4359 } 4360 } 4361 if (wtoken != null && r.mPendingRemoveWindow == null) { 4362 WindowManagerGlobal.getInstance().closeAll(wtoken, 4363 r.activity.getClass().getName(), "Activity"); 4364 } else if (r.mPendingRemoveWindow != null) { 4365 // We're preserving only one window, others should be closed so app views 4366 // will be detached before the final tear down. It should be done now because 4367 // some components (e.g. WebView) rely on detach callbacks to perform receiver 4368 // unregister and other cleanup. 4369 WindowManagerGlobal.getInstance().closeAllExceptView(token, v, 4370 r.activity.getClass().getName(), "Activity"); 4371 } 4372 r.activity.mDecor = null; 4373 } 4374 if (r.mPendingRemoveWindow == null) { 4375 // If we are delaying the removal of the activity window, then 4376 // we can't clean up all windows here. Note that we can't do 4377 // so later either, which means any windows that aren't closed 4378 // by the app will leak. Well we try to warning them a lot 4379 // about leaking windows, because that is a bug, so if they are 4380 // using this recreate facility then they get to live with leaks. 4381 WindowManagerGlobal.getInstance().closeAll(token, 4382 r.activity.getClass().getName(), "Activity"); 4383 } 4384 4385 // Mocked out contexts won't be participating in the normal 4386 // process lifecycle, but if we're running with a proper 4387 // ApplicationContext we need to have it tear down things 4388 // cleanly. 4389 Context c = r.activity.getBaseContext(); 4390 if (c instanceof ContextImpl) { 4391 ((ContextImpl) c).scheduleFinalCleanup( 4392 r.activity.getClass().getName(), "Activity"); 4393 } 4394 } 4395 if (finishing) { 4396 try { 4397 ActivityManager.getService().activityDestroyed(token); 4398 } catch (RemoteException ex) { 4399 throw ex.rethrowFromSystemServer(); 4400 } 4401 } 4402 mSomeActivitiesChanged = true; 4403 } 4404 4405 /** 4406 * @param preserveWindow Whether the activity should try to reuse the window it created, 4407 * including the decor view after the relaunch. 4408 */ 4409 public final void requestRelaunchActivity(IBinder token, 4410 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 4411 int configChanges, boolean notResumed, Configuration config, 4412 Configuration overrideConfig, boolean fromServer, boolean preserveWindow) { 4413 ActivityClientRecord target = null; 4414 4415 synchronized (mResourcesManager) { 4416 for (int i=0; i<mRelaunchingActivities.size(); i++) { 4417 ActivityClientRecord r = mRelaunchingActivities.get(i); 4418 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r); 4419 if (r.token == token) { 4420 target = r; 4421 if (pendingResults != null) { 4422 if (r.pendingResults != null) { 4423 r.pendingResults.addAll(pendingResults); 4424 } else { 4425 r.pendingResults = pendingResults; 4426 } 4427 } 4428 if (pendingNewIntents != null) { 4429 if (r.pendingIntents != null) { 4430 r.pendingIntents.addAll(pendingNewIntents); 4431 } else { 4432 r.pendingIntents = pendingNewIntents; 4433 } 4434 } 4435 4436 // For each relaunch request, activity manager expects an answer 4437 if (!r.onlyLocalRequest && fromServer) { 4438 try { 4439 ActivityManager.getService().activityRelaunched(token); 4440 } catch (RemoteException e) { 4441 throw e.rethrowFromSystemServer(); 4442 } 4443 } 4444 break; 4445 } 4446 } 4447 4448 if (target == null) { 4449 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:" 4450 + fromServer); 4451 target = new ActivityClientRecord(); 4452 target.token = token; 4453 target.pendingResults = pendingResults; 4454 target.pendingIntents = pendingNewIntents; 4455 target.mPreserveWindow = preserveWindow; 4456 if (!fromServer) { 4457 final ActivityClientRecord existing = mActivities.get(token); 4458 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing); 4459 if (existing != null) { 4460 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= " 4461 + existing.paused);; 4462 target.startsNotResumed = existing.paused; 4463 target.overrideConfig = existing.overrideConfig; 4464 } 4465 target.onlyLocalRequest = true; 4466 } 4467 mRelaunchingActivities.add(target); 4468 sendMessage(H.RELAUNCH_ACTIVITY, target); 4469 } 4470 4471 if (fromServer) { 4472 target.startsNotResumed = notResumed; 4473 target.onlyLocalRequest = false; 4474 } 4475 if (config != null) { 4476 target.createdConfig = config; 4477 } 4478 if (overrideConfig != null) { 4479 target.overrideConfig = overrideConfig; 4480 } 4481 target.pendingConfigChanges |= configChanges; 4482 target.relaunchSeq = getLifecycleSeq(); 4483 } 4484 if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this + ", target " 4485 + target + " operation received seq: " + target.relaunchSeq); 4486 } 4487 4488 private void handleRelaunchActivity(ActivityClientRecord tmp) { 4489 // If we are getting ready to gc after going to the background, well 4490 // we are back active so skip it. 4491 unscheduleGcIdler(); 4492 mSomeActivitiesChanged = true; 4493 4494 Configuration changedConfig = null; 4495 int configChanges = 0; 4496 4497 // First: make sure we have the most recent configuration and most 4498 // recent version of the activity, or skip it if some previous call 4499 // had taken a more recent version. 4500 synchronized (mResourcesManager) { 4501 int N = mRelaunchingActivities.size(); 4502 IBinder token = tmp.token; 4503 tmp = null; 4504 for (int i=0; i<N; i++) { 4505 ActivityClientRecord r = mRelaunchingActivities.get(i); 4506 if (r.token == token) { 4507 tmp = r; 4508 configChanges |= tmp.pendingConfigChanges; 4509 mRelaunchingActivities.remove(i); 4510 i--; 4511 N--; 4512 } 4513 } 4514 4515 if (tmp == null) { 4516 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 4517 return; 4518 } 4519 4520 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4521 + tmp.token + " with configChanges=0x" 4522 + Integer.toHexString(configChanges)); 4523 4524 if (mPendingConfiguration != null) { 4525 changedConfig = mPendingConfiguration; 4526 mPendingConfiguration = null; 4527 } 4528 } 4529 4530 if (tmp.lastProcessedSeq > tmp.relaunchSeq) { 4531 Slog.wtf(TAG, "For some reason target: " + tmp + " has lower sequence: " 4532 + tmp.relaunchSeq + " than current sequence: " + tmp.lastProcessedSeq); 4533 } else { 4534 tmp.lastProcessedSeq = tmp.relaunchSeq; 4535 } 4536 if (tmp.createdConfig != null) { 4537 // If the activity manager is passing us its current config, 4538 // assume that is really what we want regardless of what we 4539 // may have pending. 4540 if (mConfiguration == null 4541 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 4542 && mConfiguration.diff(tmp.createdConfig) != 0)) { 4543 if (changedConfig == null 4544 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 4545 changedConfig = tmp.createdConfig; 4546 } 4547 } 4548 } 4549 4550 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4551 + tmp.token + ": changedConfig=" + changedConfig); 4552 4553 // If there was a pending configuration change, execute it first. 4554 if (changedConfig != null) { 4555 mCurDefaultDisplayDpi = changedConfig.densityDpi; 4556 updateDefaultDensity(); 4557 handleConfigurationChanged(changedConfig, null); 4558 } 4559 4560 ActivityClientRecord r = mActivities.get(tmp.token); 4561 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 4562 if (r == null) { 4563 if (!tmp.onlyLocalRequest) { 4564 try { 4565 ActivityManager.getService().activityRelaunched(tmp.token); 4566 } catch (RemoteException e) { 4567 throw e.rethrowFromSystemServer(); 4568 } 4569 } 4570 return; 4571 } 4572 4573 r.activity.mConfigChangeFlags |= configChanges; 4574 r.onlyLocalRequest = tmp.onlyLocalRequest; 4575 r.mPreserveWindow = tmp.mPreserveWindow; 4576 r.lastProcessedSeq = tmp.lastProcessedSeq; 4577 r.relaunchSeq = tmp.relaunchSeq; 4578 Intent currentIntent = r.activity.mIntent; 4579 4580 r.activity.mChangingConfigurations = true; 4581 4582 // If we are preserving the main window across relaunches we would also like to preserve 4583 // the children. However the client side view system does not support preserving 4584 // the child views so we notify the window manager to expect these windows to 4585 // be replaced and defer requests to destroy or hide them. This way we can achieve 4586 // visual continuity. It's important that we do this here prior to pause and destroy 4587 // as that is when we may hide or remove the child views. 4588 // 4589 // There is another scenario, if we have decided locally to relaunch the app from a 4590 // call to recreate, then none of the windows will be prepared for replacement or 4591 // preserved by the server, so we want to notify it that we are preparing to replace 4592 // everything 4593 try { 4594 if (r.mPreserveWindow || r.onlyLocalRequest) { 4595 WindowManagerGlobal.getWindowSession().prepareToReplaceWindows( 4596 r.token, !r.onlyLocalRequest); 4597 } 4598 } catch (RemoteException e) { 4599 throw e.rethrowFromSystemServer(); 4600 } 4601 4602 // Need to ensure state is saved. 4603 if (!r.paused) { 4604 performPauseActivity(r.token, false, r.isPreHoneycomb(), "handleRelaunchActivity"); 4605 } 4606 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 4607 callCallActivityOnSaveInstanceState(r); 4608 } 4609 4610 handleDestroyActivity(r.token, false, configChanges, true); 4611 4612 r.activity = null; 4613 r.window = null; 4614 r.hideForNow = false; 4615 r.nextIdle = null; 4616 // Merge any pending results and pending intents; don't just replace them 4617 if (tmp.pendingResults != null) { 4618 if (r.pendingResults == null) { 4619 r.pendingResults = tmp.pendingResults; 4620 } else { 4621 r.pendingResults.addAll(tmp.pendingResults); 4622 } 4623 } 4624 if (tmp.pendingIntents != null) { 4625 if (r.pendingIntents == null) { 4626 r.pendingIntents = tmp.pendingIntents; 4627 } else { 4628 r.pendingIntents.addAll(tmp.pendingIntents); 4629 } 4630 } 4631 r.startsNotResumed = tmp.startsNotResumed; 4632 r.overrideConfig = tmp.overrideConfig; 4633 4634 handleLaunchActivity(r, currentIntent, "handleRelaunchActivity"); 4635 4636 if (!tmp.onlyLocalRequest) { 4637 try { 4638 ActivityManager.getService().activityRelaunched(r.token); 4639 if (r.window != null) { 4640 r.window.reportActivityRelaunched(); 4641 } 4642 } catch (RemoteException e) { 4643 throw e.rethrowFromSystemServer(); 4644 } 4645 } 4646 } 4647 4648 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) { 4649 r.state = new Bundle(); 4650 r.state.setAllowFds(false); 4651 if (r.isPersistable()) { 4652 r.persistentState = new PersistableBundle(); 4653 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, 4654 r.persistentState); 4655 } else { 4656 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 4657 } 4658 } 4659 4660 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 4661 boolean allActivities, Configuration newConfig) { 4662 ArrayList<ComponentCallbacks2> callbacks 4663 = new ArrayList<ComponentCallbacks2>(); 4664 4665 synchronized (mResourcesManager) { 4666 final int NAPP = mAllApplications.size(); 4667 for (int i=0; i<NAPP; i++) { 4668 callbacks.add(mAllApplications.get(i)); 4669 } 4670 final int NACT = mActivities.size(); 4671 for (int i=0; i<NACT; i++) { 4672 ActivityClientRecord ar = mActivities.valueAt(i); 4673 Activity a = ar.activity; 4674 if (a != null) { 4675 Configuration thisConfig = applyConfigCompatMainThread( 4676 mCurDefaultDisplayDpi, newConfig, 4677 ar.packageInfo.getCompatibilityInfo()); 4678 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 4679 // If the activity is currently resumed, its configuration 4680 // needs to change right now. 4681 callbacks.add(a); 4682 } else if (thisConfig != null) { 4683 // Otherwise, we will tell it about the change 4684 // the next time it is resumed or shown. Note that 4685 // the activity manager may, before then, decide the 4686 // activity needs to be destroyed to handle its new 4687 // configuration. 4688 if (DEBUG_CONFIGURATION) { 4689 Slog.v(TAG, "Setting activity " 4690 + ar.activityInfo.name + " newConfig=" + thisConfig); 4691 } 4692 ar.newConfig = thisConfig; 4693 } 4694 } 4695 } 4696 final int NSVC = mServices.size(); 4697 for (int i=0; i<NSVC; i++) { 4698 callbacks.add(mServices.valueAt(i)); 4699 } 4700 } 4701 synchronized (mProviderMap) { 4702 final int NPRV = mLocalProviders.size(); 4703 for (int i=0; i<NPRV; i++) { 4704 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 4705 } 4706 } 4707 4708 return callbacks; 4709 } 4710 4711 /** 4712 * Updates the configuration for an Activity. The ActivityClientRecord's 4713 * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for 4714 * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering 4715 * the updated Configuration. 4716 * @param r ActivityClientRecord representing the Activity. 4717 * @param newBaseConfig The new configuration to use. This may be augmented with 4718 * {@link ActivityClientRecord#overrideConfig}. 4719 * @param reportToActivity true if the change should be reported to the Activity's callback. 4720 */ 4721 private void performConfigurationChangedForActivity(ActivityClientRecord r, 4722 Configuration newBaseConfig, 4723 boolean reportToActivity) { 4724 r.tmpConfig.setTo(newBaseConfig); 4725 if (r.overrideConfig != null) { 4726 r.tmpConfig.updateFrom(r.overrideConfig); 4727 } 4728 performConfigurationChanged(r.activity, r.token, r.tmpConfig, r.overrideConfig, 4729 reportToActivity); 4730 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 4731 } 4732 4733 /** 4734 * Creates a new Configuration only if override would modify base. Otherwise returns base. 4735 * @param base The base configuration. 4736 * @param override The update to apply to the base configuration. Can be null. 4737 * @return A Configuration representing base with override applied. 4738 */ 4739 private static Configuration createNewConfigAndUpdateIfNotNull(@NonNull Configuration base, 4740 @Nullable Configuration override) { 4741 if (override == null) { 4742 return base; 4743 } 4744 Configuration newConfig = new Configuration(base); 4745 newConfig.updateFrom(override); 4746 return newConfig; 4747 } 4748 4749 /** 4750 * Decides whether to update an Activity's configuration and whether to tell the 4751 * Activity/Component about it. 4752 * @param cb The component callback to notify of configuration change. 4753 * @param activityToken The Activity binder token for which this configuration change happened. 4754 * If the change is global, this is null. 4755 * @param newConfig The new configuration. 4756 * @param amOverrideConfig The override config that differentiates the Activity's configuration 4757 * from the base global configuration. 4758 * This is supplied by ActivityManager. 4759 * @param reportToActivity Notify the Activity of the change. 4760 */ 4761 private void performConfigurationChanged(ComponentCallbacks2 cb, 4762 IBinder activityToken, 4763 Configuration newConfig, 4764 Configuration amOverrideConfig, 4765 boolean reportToActivity) { 4766 // Only for Activity objects, check that they actually call up to their 4767 // superclass implementation. ComponentCallbacks2 is an interface, so 4768 // we check the runtime type and act accordingly. 4769 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 4770 if (activity != null) { 4771 activity.mCalled = false; 4772 } 4773 4774 boolean shouldChangeConfig = false; 4775 if ((activity == null) || (activity.mCurrentConfig == null)) { 4776 shouldChangeConfig = true; 4777 } else { 4778 // If the new config is the same as the config this Activity is already 4779 // running with and the override config also didn't change, then don't 4780 // bother calling onConfigurationChanged. 4781 int diff = activity.mCurrentConfig.diff(newConfig); 4782 if (diff != 0 || !mResourcesManager.isSameResourcesOverrideConfig(activityToken, 4783 amOverrideConfig)) { 4784 // Always send the task-level config changes. For system-level configuration, if 4785 // this activity doesn't handle any of the config changes, then don't bother 4786 // calling onConfigurationChanged as we're going to destroy it. 4787 if (!mUpdatingSystemConfig 4788 || (~activity.mActivityInfo.getRealConfigChanged() & diff) == 0 4789 || !reportToActivity) { 4790 shouldChangeConfig = true; 4791 } 4792 } 4793 } 4794 4795 if (shouldChangeConfig) { 4796 // Propagate the configuration change to the Activity and ResourcesManager. 4797 4798 // ContextThemeWrappers may override the configuration for that context. 4799 // We must check and apply any overrides defined. 4800 Configuration contextThemeWrapperOverrideConfig = null; 4801 if (cb instanceof ContextThemeWrapper) { 4802 final ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb; 4803 contextThemeWrapperOverrideConfig = contextThemeWrapper.getOverrideConfiguration(); 4804 } 4805 4806 // We only update an Activity's configuration if this is not a global 4807 // configuration change. This must also be done before the callback, 4808 // or else we violate the contract that the new resources are available 4809 // in {@link ComponentCallbacks2#onConfigurationChanged(Configuration)}. 4810 if (activityToken != null) { 4811 // Apply the ContextThemeWrapper override if necessary. 4812 // NOTE: Make sure the configurations are not modified, as they are treated 4813 // as immutable in many places. 4814 final Configuration finalOverrideConfig = createNewConfigAndUpdateIfNotNull( 4815 amOverrideConfig, contextThemeWrapperOverrideConfig); 4816 mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig); 4817 } 4818 4819 if (reportToActivity) { 4820 // Apply the ContextThemeWrapper override if necessary. 4821 // NOTE: Make sure the configurations are not modified, as they are treated 4822 // as immutable in many places. 4823 final Configuration configToReport = createNewConfigAndUpdateIfNotNull( 4824 newConfig, contextThemeWrapperOverrideConfig); 4825 cb.onConfigurationChanged(configToReport); 4826 } 4827 4828 if (activity != null) { 4829 if (reportToActivity && !activity.mCalled) { 4830 throw new SuperNotCalledException( 4831 "Activity " + activity.getLocalClassName() + 4832 " did not call through to super.onConfigurationChanged()"); 4833 } 4834 activity.mConfigChangeFlags = 0; 4835 activity.mCurrentConfig = new Configuration(newConfig); 4836 } 4837 } 4838 } 4839 4840 public final void applyConfigurationToResources(Configuration config) { 4841 synchronized (mResourcesManager) { 4842 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 4843 } 4844 } 4845 4846 final Configuration applyCompatConfiguration(int displayDensity) { 4847 Configuration config = mConfiguration; 4848 if (mCompatConfiguration == null) { 4849 mCompatConfiguration = new Configuration(); 4850 } 4851 mCompatConfiguration.setTo(mConfiguration); 4852 if (mResourcesManager.applyCompatConfigurationLocked(displayDensity, 4853 mCompatConfiguration)) { 4854 config = mCompatConfiguration; 4855 } 4856 return config; 4857 } 4858 4859 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 4860 4861 int configDiff = 0; 4862 4863 synchronized (mResourcesManager) { 4864 if (mPendingConfiguration != null) { 4865 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 4866 config = mPendingConfiguration; 4867 mCurDefaultDisplayDpi = config.densityDpi; 4868 updateDefaultDensity(); 4869 } 4870 mPendingConfiguration = null; 4871 } 4872 4873 if (config == null) { 4874 return; 4875 } 4876 4877 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 4878 + config); 4879 4880 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 4881 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), 4882 mResourcesManager.getConfiguration().getLocales()); 4883 4884 if (mConfiguration == null) { 4885 mConfiguration = new Configuration(); 4886 } 4887 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 4888 return; 4889 } 4890 4891 configDiff = mConfiguration.updateFrom(config); 4892 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 4893 4894 final Theme systemTheme = getSystemContext().getTheme(); 4895 if ((systemTheme.getChangingConfigurations() & configDiff) != 0) { 4896 systemTheme.rebase(); 4897 } 4898 } 4899 4900 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 4901 4902 freeTextLayoutCachesIfNeeded(configDiff); 4903 4904 if (callbacks != null) { 4905 final int N = callbacks.size(); 4906 for (int i=0; i<N; i++) { 4907 ComponentCallbacks2 cb = callbacks.get(i); 4908 if (cb instanceof Activity) { 4909 // If callback is an Activity - call corresponding method to consider override 4910 // config and avoid onConfigurationChanged if it hasn't changed. 4911 Activity a = (Activity) cb; 4912 performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()), 4913 config, REPORT_TO_ACTIVITY); 4914 } else { 4915 performConfigurationChanged(cb, null, config, null, REPORT_TO_ACTIVITY); 4916 } 4917 } 4918 } 4919 } 4920 4921 void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) { 4922 synchronized (mResourcesManager) { 4923 // Update all affected loaded packages with new package information 4924 WeakReference<LoadedApk> ref = mPackages.get(ai.packageName); 4925 LoadedApk apk = ref != null ? ref.get() : null; 4926 if (apk != null) { 4927 apk.updateApplicationInfo(ai, null); 4928 } 4929 4930 ref = mResourcePackages.get(ai.packageName); 4931 apk = ref != null ? ref.get() : null; 4932 if (apk != null) { 4933 apk.updateApplicationInfo(ai, null); 4934 } 4935 4936 // Update all affected Resources objects to use new ResourcesImpl 4937 mResourcesManager.applyNewResourceDirsLocked(ai.sourceDir, ai.resourceDirs); 4938 } 4939 4940 ApplicationPackageManager.configurationChanged(); 4941 4942 // Trigger a regular Configuration change event, only with a different assetsSeq number 4943 // so that we actually call through to all components. 4944 Configuration newConfig = new Configuration(); 4945 newConfig.unset(); 4946 newConfig.assetsSeq = mConfiguration.assetsSeq + 1; 4947 handleConfigurationChanged(newConfig, null); 4948 4949 // Schedule all activities to reload 4950 for (final Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { 4951 final Activity activity = entry.getValue().activity; 4952 if (!activity.mFinished) { 4953 requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false, 4954 false); 4955 } 4956 } 4957 } 4958 4959 static void freeTextLayoutCachesIfNeeded(int configDiff) { 4960 if (configDiff != 0) { 4961 // Ask text layout engine to free its caches if there is a locale change 4962 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 4963 if (hasLocaleConfigChange) { 4964 Canvas.freeTextLayoutCaches(); 4965 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 4966 } 4967 } 4968 } 4969 4970 final void handleActivityConfigurationChanged(ActivityConfigChangeData data, 4971 boolean reportToActivity) { 4972 ActivityClientRecord r = mActivities.get(data.activityToken); 4973 if (r == null || r.activity == null) { 4974 return; 4975 } 4976 4977 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 4978 + r.activityInfo.name + ", with callback=" + reportToActivity); 4979 4980 r.overrideConfig = data.overrideConfig; 4981 performConfigurationChangedForActivity(r, mCompatConfiguration, reportToActivity); 4982 mSomeActivitiesChanged = true; 4983 } 4984 4985 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 4986 if (start) { 4987 try { 4988 switch (profileType) { 4989 default: 4990 mProfiler.setProfiler(profilerInfo); 4991 mProfiler.startProfiling(); 4992 break; 4993 } 4994 } catch (RuntimeException e) { 4995 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile 4996 + " -- can the process access this path?"); 4997 } finally { 4998 try { 4999 profilerInfo.profileFd.close(); 5000 } catch (IOException e) { 5001 Slog.w(TAG, "Failure closing profile fd", e); 5002 } 5003 } 5004 } else { 5005 switch (profileType) { 5006 default: 5007 mProfiler.stopProfiling(); 5008 break; 5009 } 5010 } 5011 } 5012 5013 /** 5014 * Public entrypoint to stop profiling. This is required to end profiling when the app crashes, 5015 * so that profiler data won't be lost. 5016 * 5017 * @hide 5018 */ 5019 public void stopProfiling() { 5020 mProfiler.stopProfiling(); 5021 } 5022 5023 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 5024 if (managed) { 5025 try { 5026 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 5027 } catch (IOException e) { 5028 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 5029 + " -- can the process access this path?"); 5030 } finally { 5031 try { 5032 dhd.fd.close(); 5033 } catch (IOException e) { 5034 Slog.w(TAG, "Failure closing profile fd", e); 5035 } 5036 } 5037 } else { 5038 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 5039 } 5040 try { 5041 ActivityManager.getService().dumpHeapFinished(dhd.path); 5042 } catch (RemoteException e) { 5043 throw e.rethrowFromSystemServer(); 5044 } 5045 } 5046 5047 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 5048 boolean hasPkgInfo = false; 5049 switch (cmd) { 5050 case ApplicationThreadConstants.PACKAGE_REMOVED: 5051 case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL: 5052 { 5053 final boolean killApp = cmd == ApplicationThreadConstants.PACKAGE_REMOVED; 5054 if (packages == null) { 5055 break; 5056 } 5057 synchronized (mResourcesManager) { 5058 for (int i = packages.length - 1; i >= 0; i--) { 5059 if (!hasPkgInfo) { 5060 WeakReference<LoadedApk> ref = mPackages.get(packages[i]); 5061 if (ref != null && ref.get() != null) { 5062 hasPkgInfo = true; 5063 } else { 5064 ref = mResourcePackages.get(packages[i]); 5065 if (ref != null && ref.get() != null) { 5066 hasPkgInfo = true; 5067 } 5068 } 5069 } 5070 if (killApp) { 5071 mPackages.remove(packages[i]); 5072 mResourcePackages.remove(packages[i]); 5073 } 5074 } 5075 } 5076 break; 5077 } 5078 case ApplicationThreadConstants.PACKAGE_REPLACED: 5079 { 5080 if (packages == null) { 5081 break; 5082 } 5083 synchronized (mResourcesManager) { 5084 for (int i = packages.length - 1; i >= 0; i--) { 5085 WeakReference<LoadedApk> ref = mPackages.get(packages[i]); 5086 LoadedApk pkgInfo = ref != null ? ref.get() : null; 5087 if (pkgInfo != null) { 5088 hasPkgInfo = true; 5089 } else { 5090 ref = mResourcePackages.get(packages[i]); 5091 pkgInfo = ref != null ? ref.get() : null; 5092 if (pkgInfo != null) { 5093 hasPkgInfo = true; 5094 } 5095 } 5096 // If the package is being replaced, yet it still has a valid 5097 // LoadedApk object, the package was updated with _DONT_KILL. 5098 // Adjust it's internal references to the application info and 5099 // resources. 5100 if (pkgInfo != null) { 5101 try { 5102 final String packageName = packages[i]; 5103 final ApplicationInfo aInfo = 5104 sPackageManager.getApplicationInfo( 5105 packageName, 5106 0 /*flags*/, 5107 UserHandle.myUserId()); 5108 5109 if (mActivities.size() > 0) { 5110 for (ActivityClientRecord ar : mActivities.values()) { 5111 if (ar.activityInfo.applicationInfo.packageName 5112 .equals(packageName)) { 5113 ar.activityInfo.applicationInfo = aInfo; 5114 ar.packageInfo = pkgInfo; 5115 } 5116 } 5117 } 5118 final List<String> oldPaths = 5119 sPackageManager.getPreviousCodePaths(packageName); 5120 pkgInfo.updateApplicationInfo(aInfo, oldPaths); 5121 } catch (RemoteException e) { 5122 } 5123 } 5124 } 5125 } 5126 break; 5127 } 5128 } 5129 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo); 5130 } 5131 5132 final void handleLowMemory() { 5133 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 5134 5135 final int N = callbacks.size(); 5136 for (int i=0; i<N; i++) { 5137 callbacks.get(i).onLowMemory(); 5138 } 5139 5140 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 5141 if (Process.myUid() != Process.SYSTEM_UID) { 5142 int sqliteReleased = SQLiteDatabase.releaseMemory(); 5143 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 5144 } 5145 5146 // Ask graphics to free up as much as possible (font/image caches) 5147 Canvas.freeCaches(); 5148 5149 // Ask text layout engine to free also as much as possible 5150 Canvas.freeTextLayoutCaches(); 5151 5152 BinderInternal.forceGc("mem"); 5153 } 5154 5155 final void handleTrimMemory(int level) { 5156 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 5157 5158 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 5159 5160 final int N = callbacks.size(); 5161 for (int i = 0; i < N; i++) { 5162 callbacks.get(i).onTrimMemory(level); 5163 } 5164 5165 WindowManagerGlobal.getInstance().trimMemory(level); 5166 } 5167 5168 private void setupGraphicsSupport(Context context, File cacheDir) { 5169 if (Process.isIsolated()) { 5170 // Isolated processes aren't going to do UI. 5171 return; 5172 } 5173 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport"); 5174 try { 5175 int uid = Process.myUid(); 5176 String[] packages = getPackageManager().getPackagesForUid(uid); 5177 5178 if (packages != null) { 5179 ThreadedRenderer.setupDiskCache(cacheDir); 5180 RenderScriptCacheDir.setupDiskCache(cacheDir); 5181 GraphicsEnvironment.setupGraphicsEnvironment(context); 5182 } 5183 } catch (RemoteException e) { 5184 throw e.rethrowFromSystemServer(); 5185 } finally { 5186 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5187 } 5188 } 5189 5190 private void updateDefaultDensity() { 5191 final int densityDpi = mCurDefaultDisplayDpi; 5192 if (!mDensityCompatMode 5193 && densityDpi != Configuration.DENSITY_DPI_UNDEFINED 5194 && densityDpi != DisplayMetrics.DENSITY_DEVICE) { 5195 DisplayMetrics.DENSITY_DEVICE = densityDpi; 5196 Bitmap.setDefaultDensity(densityDpi); 5197 } 5198 } 5199 5200 /** 5201 * Returns the correct library directory for the current ABI. 5202 * <p> 5203 * If we're dealing with a multi-arch application that has both 32 and 64 bit shared 5204 * libraries, we might need to choose the secondary depending on what the current 5205 * runtime's instruction set is. 5206 */ 5207 private String getInstrumentationLibrary(ApplicationInfo appInfo, InstrumentationInfo insInfo) { 5208 if (appInfo.primaryCpuAbi != null && appInfo.secondaryCpuAbi != null) { 5209 // Get the instruction set supported by the secondary ABI. In the presence 5210 // of a native bridge this might be different than the one secondary ABI used. 5211 String secondaryIsa = 5212 VMRuntime.getInstructionSet(appInfo.secondaryCpuAbi); 5213 final String secondaryDexCodeIsa = 5214 SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa); 5215 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa; 5216 5217 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet(); 5218 if (runtimeIsa.equals(secondaryIsa)) { 5219 return insInfo.secondaryNativeLibraryDir; 5220 } 5221 } 5222 return insInfo.nativeLibraryDir; 5223 } 5224 5225 /** 5226 * The LocaleList set for the app's resources may have been shuffled so that the preferred 5227 * Locale is at position 0. We must find the index of this preferred Locale in the 5228 * original LocaleList. 5229 */ 5230 private void updateLocaleListFromAppContext(Context context, LocaleList newLocaleList) { 5231 final Locale bestLocale = context.getResources().getConfiguration().getLocales().get(0); 5232 final int newLocaleListSize = newLocaleList.size(); 5233 for (int i = 0; i < newLocaleListSize; i++) { 5234 if (bestLocale.equals(newLocaleList.get(i))) { 5235 LocaleList.setDefault(newLocaleList, i); 5236 return; 5237 } 5238 } 5239 5240 // The app may have overridden the LocaleList with its own Locale 5241 // (not present in the available list). Push the chosen Locale 5242 // to the front of the list. 5243 LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList)); 5244 } 5245 5246 private void handleBindApplication(AppBindData data) { 5247 // Register the UI Thread as a sensitive thread to the runtime. 5248 VMRuntime.registerSensitiveThread(); 5249 if (data.trackAllocation) { 5250 DdmVmInternal.enableRecentAllocations(true); 5251 } 5252 5253 // Note when this process has started. 5254 Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); 5255 5256 mBoundApplication = data; 5257 mConfiguration = new Configuration(data.config); 5258 mCompatConfiguration = new Configuration(data.config); 5259 5260 mProfiler = new Profiler(); 5261 if (data.initProfilerInfo != null) { 5262 mProfiler.profileFile = data.initProfilerInfo.profileFile; 5263 mProfiler.profileFd = data.initProfilerInfo.profileFd; 5264 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; 5265 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; 5266 } 5267 5268 // send up app name; do this *before* waiting for debugger 5269 Process.setArgV0(data.processName); 5270 android.ddm.DdmHandleAppName.setAppName(data.processName, 5271 UserHandle.myUserId()); 5272 5273 if (data.persistent) { 5274 // Persistent processes on low-memory devices do not get to 5275 // use hardware accelerated drawing, since this can add too much 5276 // overhead to the process. 5277 if (!ActivityManager.isHighEndGfx()) { 5278 ThreadedRenderer.disable(false); 5279 } 5280 } 5281 5282 if (mProfiler.profileFd != null) { 5283 mProfiler.startProfiling(); 5284 } 5285 5286 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 5287 // implementation to use the pool executor. Normally, we use the 5288 // serialized executor as the default. This has to happen in the 5289 // main thread so the main looper is set right. 5290 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 5291 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 5292 } 5293 5294 Message.updateCheckRecycle(data.appInfo.targetSdkVersion); 5295 5296 /* 5297 * Before spawning a new process, reset the time zone to be the system time zone. 5298 * This needs to be done because the system time zone could have changed after the 5299 * the spawning of this process. Without doing this this process would have the incorrect 5300 * system time zone. 5301 */ 5302 TimeZone.setDefault(null); 5303 5304 /* 5305 * Set the LocaleList. This may change once we create the App Context. 5306 */ 5307 LocaleList.setDefault(data.config.getLocales()); 5308 5309 synchronized (mResourcesManager) { 5310 /* 5311 * Update the system configuration since its preloaded and might not 5312 * reflect configuration changes. The configuration object passed 5313 * in AppBindData can be safely assumed to be up to date 5314 */ 5315 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 5316 mCurDefaultDisplayDpi = data.config.densityDpi; 5317 5318 // This calls mResourcesManager so keep it within the synchronized block. 5319 applyCompatConfiguration(mCurDefaultDisplayDpi); 5320 } 5321 5322 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 5323 5324 /** 5325 * Switch this process to density compatibility mode if needed. 5326 */ 5327 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 5328 == 0) { 5329 mDensityCompatMode = true; 5330 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 5331 } 5332 updateDefaultDensity(); 5333 5334 final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24); 5335 Boolean is24Hr = null; 5336 if (use24HourSetting != null) { 5337 is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE; 5338 } 5339 // null : use locale default for 12/24 hour formatting, 5340 // false : use 12 hour format, 5341 // true : use 24 hour format. 5342 DateFormat.set24HourTimePref(is24Hr); 5343 5344 View.mDebugViewAttributes = 5345 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 5346 5347 /** 5348 * For system applications on userdebug/eng builds, log stack 5349 * traces of disk and network access to dropbox for analysis. 5350 */ 5351 if ((data.appInfo.flags & 5352 (ApplicationInfo.FLAG_SYSTEM | 5353 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 5354 StrictMode.conditionallyEnableDebugLogging(); 5355 } 5356 5357 /** 5358 * For apps targetting Honeycomb or later, we don't allow network usage 5359 * on the main event loop / UI thread. This is what ultimately throws 5360 * {@link NetworkOnMainThreadException}. 5361 */ 5362 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) { 5363 StrictMode.enableDeathOnNetwork(); 5364 } 5365 5366 /** 5367 * For apps targetting N or later, we don't allow file:// Uri exposure. 5368 * This is what ultimately throws {@link FileUriExposedException}. 5369 */ 5370 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 5371 StrictMode.enableDeathOnFileUriExposure(); 5372 } 5373 5374 // We deprecated Build.SERIAL and only apps that target pre NMR1 5375 // SDK can see it. Since access to the serial is now behind a 5376 // permission we push down the value and here we fix it up 5377 // before any app code has been loaded. 5378 try { 5379 Field field = Build.class.getDeclaredField("SERIAL"); 5380 field.setAccessible(true); 5381 field.set(Build.class, data.buildSerial); 5382 } catch (NoSuchFieldException | IllegalAccessException e) { 5383 /* ignore */ 5384 } 5385 5386 if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) { 5387 // XXX should have option to change the port. 5388 Debug.changeDebugPort(8100); 5389 if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) { 5390 Slog.w(TAG, "Application " + data.info.getPackageName() 5391 + " is waiting for the debugger on port 8100..."); 5392 5393 IActivityManager mgr = ActivityManager.getService(); 5394 try { 5395 mgr.showWaitingForDebugger(mAppThread, true); 5396 } catch (RemoteException ex) { 5397 throw ex.rethrowFromSystemServer(); 5398 } 5399 5400 Debug.waitForDebugger(); 5401 5402 try { 5403 mgr.showWaitingForDebugger(mAppThread, false); 5404 } catch (RemoteException ex) { 5405 throw ex.rethrowFromSystemServer(); 5406 } 5407 5408 } else { 5409 Slog.w(TAG, "Application " + data.info.getPackageName() 5410 + " can be debugged on port 8100..."); 5411 } 5412 } 5413 5414 // Allow application-generated systrace messages if we're debuggable. 5415 boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 5416 Trace.setAppTracingAllowed(isAppDebuggable); 5417 if (isAppDebuggable && data.enableBinderTracking) { 5418 Binder.enableTracing(); 5419 } 5420 5421 /** 5422 * Initialize the default http proxy in this process for the reasons we set the time zone. 5423 */ 5424 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies"); 5425 final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 5426 if (b != null) { 5427 // In pre-boot mode (doing initial launch to collect password), not 5428 // all system is up. This includes the connectivity service, so don't 5429 // crash if we can't get it. 5430 final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 5431 try { 5432 final ProxyInfo proxyInfo = service.getProxyForNetwork(null); 5433 Proxy.setHttpProxySystemProperty(proxyInfo); 5434 } catch (RemoteException e) { 5435 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5436 throw e.rethrowFromSystemServer(); 5437 } 5438 } 5439 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5440 5441 // Instrumentation info affects the class loader, so load it before 5442 // setting up the app context. 5443 final InstrumentationInfo ii; 5444 if (data.instrumentationName != null) { 5445 try { 5446 ii = new ApplicationPackageManager(null, getPackageManager()) 5447 .getInstrumentationInfo(data.instrumentationName, 0); 5448 } catch (PackageManager.NameNotFoundException e) { 5449 throw new RuntimeException( 5450 "Unable to find instrumentation info for: " + data.instrumentationName); 5451 } 5452 5453 mInstrumentationPackageName = ii.packageName; 5454 mInstrumentationAppDir = ii.sourceDir; 5455 mInstrumentationSplitAppDirs = ii.splitSourceDirs; 5456 mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); 5457 mInstrumentedAppDir = data.info.getAppDir(); 5458 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); 5459 mInstrumentedLibDir = data.info.getLibDir(); 5460 } else { 5461 ii = null; 5462 } 5463 5464 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 5465 updateLocaleListFromAppContext(appContext, 5466 mResourcesManager.getConfiguration().getLocales()); 5467 5468 if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) { 5469 // This cache location probably points at credential-encrypted 5470 // storage which may not be accessible yet; assign it anyway instead 5471 // of pointing at device-encrypted storage. 5472 final File cacheDir = appContext.getCacheDir(); 5473 if (cacheDir != null) { 5474 // Provide a usable directory for temporary files 5475 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 5476 } else { 5477 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property " 5478 + "due to missing cache directory"); 5479 } 5480 5481 // Setup a location to store generated/compiled graphics code. 5482 final Context deviceContext = appContext.createDeviceProtectedStorageContext(); 5483 final File codeCacheDir = deviceContext.getCodeCacheDir(); 5484 if (codeCacheDir != null) { 5485 setupGraphicsSupport(appContext, codeCacheDir); 5486 } else { 5487 Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory"); 5488 } 5489 } 5490 5491 // Install the Network Security Config Provider. This must happen before the application 5492 // code is loaded to prevent issues with instances of TLS objects being created before 5493 // the provider is installed. 5494 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "NetworkSecurityConfigProvider.install"); 5495 NetworkSecurityConfigProvider.install(appContext); 5496 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5497 5498 // Continue loading instrumentation. 5499 if (ii != null) { 5500 final ApplicationInfo instrApp = new ApplicationInfo(); 5501 ii.copyTo(instrApp); 5502 instrApp.initForUser(UserHandle.myUserId()); 5503 final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 5504 appContext.getClassLoader(), false, true, false); 5505 final ContextImpl instrContext = ContextImpl.createAppContext(this, pi); 5506 5507 try { 5508 final ClassLoader cl = instrContext.getClassLoader(); 5509 mInstrumentation = (Instrumentation) 5510 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 5511 } catch (Exception e) { 5512 throw new RuntimeException( 5513 "Unable to instantiate instrumentation " 5514 + data.instrumentationName + ": " + e.toString(), e); 5515 } 5516 5517 final ComponentName component = new ComponentName(ii.packageName, ii.name); 5518 mInstrumentation.init(this, instrContext, appContext, component, 5519 data.instrumentationWatcher, data.instrumentationUiAutomationConnection); 5520 5521 if (mProfiler.profileFile != null && !ii.handleProfiling 5522 && mProfiler.profileFd == null) { 5523 mProfiler.handlingProfiling = true; 5524 final File file = new File(mProfiler.profileFile); 5525 file.getParentFile().mkdirs(); 5526 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 5527 } 5528 } else { 5529 mInstrumentation = new Instrumentation(); 5530 } 5531 5532 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 5533 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 5534 } else { 5535 // Small heap, clamp to the current growth limit and let the heap release 5536 // pages after the growth limit to the non growth limit capacity. b/18387825 5537 dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); 5538 } 5539 5540 // Allow disk access during application and provider setup. This could 5541 // block processing ordered broadcasts, but later processing would 5542 // probably end up doing the same disk access. 5543 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 5544 try { 5545 // If the app is being launched for full backup or restore, bring it up in 5546 // a restricted environment with the base application class. 5547 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 5548 mInitialApplication = app; 5549 5550 // don't bring up providers in restricted mode; they may depend on the 5551 // app's custom Application class 5552 if (!data.restrictedBackupMode) { 5553 if (!ArrayUtils.isEmpty(data.providers)) { 5554 installContentProviders(app, data.providers); 5555 // For process that contains content providers, we want to 5556 // ensure that the JIT is enabled "at some point". 5557 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 5558 } 5559 } 5560 5561 // Do this after providers, since instrumentation tests generally start their 5562 // test thread at this point, and we don't want that racing. 5563 try { 5564 mInstrumentation.onCreate(data.instrumentationArgs); 5565 } 5566 catch (Exception e) { 5567 throw new RuntimeException( 5568 "Exception thrown in onCreate() of " 5569 + data.instrumentationName + ": " + e.toString(), e); 5570 } 5571 5572 try { 5573 mInstrumentation.callApplicationOnCreate(app); 5574 } catch (Exception e) { 5575 if (!mInstrumentation.onException(app, e)) { 5576 throw new RuntimeException( 5577 "Unable to create application " + app.getClass().getName() 5578 + ": " + e.toString(), e); 5579 } 5580 } 5581 } finally { 5582 StrictMode.setThreadPolicy(savedPolicy); 5583 } 5584 } 5585 5586 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 5587 IActivityManager am = ActivityManager.getService(); 5588 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 5589 && mProfiler.profileFd == null) { 5590 Debug.stopMethodTracing(); 5591 } 5592 //Slog.i(TAG, "am: " + ActivityManager.getService() 5593 // + ", app thr: " + mAppThread); 5594 try { 5595 am.finishInstrumentation(mAppThread, resultCode, results); 5596 } catch (RemoteException ex) { 5597 throw ex.rethrowFromSystemServer(); 5598 } 5599 } 5600 5601 private void installContentProviders( 5602 Context context, List<ProviderInfo> providers) { 5603 final ArrayList<ContentProviderHolder> results = new ArrayList<>(); 5604 5605 for (ProviderInfo cpi : providers) { 5606 if (DEBUG_PROVIDER) { 5607 StringBuilder buf = new StringBuilder(128); 5608 buf.append("Pub "); 5609 buf.append(cpi.authority); 5610 buf.append(": "); 5611 buf.append(cpi.name); 5612 Log.i(TAG, buf.toString()); 5613 } 5614 ContentProviderHolder cph = installProvider(context, null, cpi, 5615 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 5616 if (cph != null) { 5617 cph.noReleaseNeeded = true; 5618 results.add(cph); 5619 } 5620 } 5621 5622 try { 5623 ActivityManager.getService().publishContentProviders( 5624 getApplicationThread(), results); 5625 } catch (RemoteException ex) { 5626 throw ex.rethrowFromSystemServer(); 5627 } 5628 } 5629 5630 public final IContentProvider acquireProvider( 5631 Context c, String auth, int userId, boolean stable) { 5632 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 5633 if (provider != null) { 5634 return provider; 5635 } 5636 5637 // There is a possible race here. Another thread may try to acquire 5638 // the same provider at the same time. When this happens, we want to ensure 5639 // that the first one wins. 5640 // Note that we cannot hold the lock while acquiring and installing the 5641 // provider since it might take a long time to run and it could also potentially 5642 // be re-entrant in the case where the provider is in the same process. 5643 ContentProviderHolder holder = null; 5644 try { 5645 holder = ActivityManager.getService().getContentProvider( 5646 getApplicationThread(), auth, userId, stable); 5647 } catch (RemoteException ex) { 5648 throw ex.rethrowFromSystemServer(); 5649 } 5650 if (holder == null) { 5651 Slog.e(TAG, "Failed to find provider info for " + auth); 5652 return null; 5653 } 5654 5655 // Install provider will increment the reference count for us, and break 5656 // any ties in the race. 5657 holder = installProvider(c, holder, holder.info, 5658 true /*noisy*/, holder.noReleaseNeeded, stable); 5659 return holder.provider; 5660 } 5661 5662 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 5663 if (stable) { 5664 prc.stableCount += 1; 5665 if (prc.stableCount == 1) { 5666 // We are acquiring a new stable reference on the provider. 5667 int unstableDelta; 5668 if (prc.removePending) { 5669 // We have a pending remove operation, which is holding the 5670 // last unstable reference. At this point we are converting 5671 // that unstable reference to our new stable reference. 5672 unstableDelta = -1; 5673 // Cancel the removal of the provider. 5674 if (DEBUG_PROVIDER) { 5675 Slog.v(TAG, "incProviderRef: stable " 5676 + "snatched provider from the jaws of death"); 5677 } 5678 prc.removePending = false; 5679 // There is a race! It fails to remove the message, which 5680 // will be handled in completeRemoveProvider(). 5681 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5682 } else { 5683 unstableDelta = 0; 5684 } 5685 try { 5686 if (DEBUG_PROVIDER) { 5687 Slog.v(TAG, "incProviderRef Now stable - " 5688 + prc.holder.info.name + ": unstableDelta=" 5689 + unstableDelta); 5690 } 5691 ActivityManager.getService().refContentProvider( 5692 prc.holder.connection, 1, unstableDelta); 5693 } catch (RemoteException e) { 5694 //do nothing content provider object is dead any way 5695 } 5696 } 5697 } else { 5698 prc.unstableCount += 1; 5699 if (prc.unstableCount == 1) { 5700 // We are acquiring a new unstable reference on the provider. 5701 if (prc.removePending) { 5702 // Oh look, we actually have a remove pending for the 5703 // provider, which is still holding the last unstable 5704 // reference. We just need to cancel that to take new 5705 // ownership of the reference. 5706 if (DEBUG_PROVIDER) { 5707 Slog.v(TAG, "incProviderRef: unstable " 5708 + "snatched provider from the jaws of death"); 5709 } 5710 prc.removePending = false; 5711 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5712 } else { 5713 // First unstable ref, increment our count in the 5714 // activity manager. 5715 try { 5716 if (DEBUG_PROVIDER) { 5717 Slog.v(TAG, "incProviderRef: Now unstable - " 5718 + prc.holder.info.name); 5719 } 5720 ActivityManager.getService().refContentProvider( 5721 prc.holder.connection, 0, 1); 5722 } catch (RemoteException e) { 5723 //do nothing content provider object is dead any way 5724 } 5725 } 5726 } 5727 } 5728 } 5729 5730 public final IContentProvider acquireExistingProvider( 5731 Context c, String auth, int userId, boolean stable) { 5732 synchronized (mProviderMap) { 5733 final ProviderKey key = new ProviderKey(auth, userId); 5734 final ProviderClientRecord pr = mProviderMap.get(key); 5735 if (pr == null) { 5736 return null; 5737 } 5738 5739 IContentProvider provider = pr.mProvider; 5740 IBinder jBinder = provider.asBinder(); 5741 if (!jBinder.isBinderAlive()) { 5742 // The hosting process of the provider has died; we can't 5743 // use this one. 5744 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 5745 + ": existing object's process dead"); 5746 handleUnstableProviderDiedLocked(jBinder, true); 5747 return null; 5748 } 5749 5750 // Only increment the ref count if we have one. If we don't then the 5751 // provider is not reference counted and never needs to be released. 5752 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5753 if (prc != null) { 5754 incProviderRefLocked(prc, stable); 5755 } 5756 return provider; 5757 } 5758 } 5759 5760 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 5761 if (provider == null) { 5762 return false; 5763 } 5764 5765 IBinder jBinder = provider.asBinder(); 5766 synchronized (mProviderMap) { 5767 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5768 if (prc == null) { 5769 // The provider has no ref count, no release is needed. 5770 return false; 5771 } 5772 5773 boolean lastRef = false; 5774 if (stable) { 5775 if (prc.stableCount == 0) { 5776 if (DEBUG_PROVIDER) Slog.v(TAG, 5777 "releaseProvider: stable ref count already 0, how?"); 5778 return false; 5779 } 5780 prc.stableCount -= 1; 5781 if (prc.stableCount == 0) { 5782 // What we do at this point depends on whether there are 5783 // any unstable refs left: if there are, we just tell the 5784 // activity manager to decrement its stable count; if there 5785 // aren't, we need to enqueue this provider to be removed, 5786 // and convert to holding a single unstable ref while 5787 // doing so. 5788 lastRef = prc.unstableCount == 0; 5789 try { 5790 if (DEBUG_PROVIDER) { 5791 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 5792 + lastRef + " - " + prc.holder.info.name); 5793 } 5794 ActivityManager.getService().refContentProvider( 5795 prc.holder.connection, -1, lastRef ? 1 : 0); 5796 } catch (RemoteException e) { 5797 //do nothing content provider object is dead any way 5798 } 5799 } 5800 } else { 5801 if (prc.unstableCount == 0) { 5802 if (DEBUG_PROVIDER) Slog.v(TAG, 5803 "releaseProvider: unstable ref count already 0, how?"); 5804 return false; 5805 } 5806 prc.unstableCount -= 1; 5807 if (prc.unstableCount == 0) { 5808 // If this is the last reference, we need to enqueue 5809 // this provider to be removed instead of telling the 5810 // activity manager to remove it at this point. 5811 lastRef = prc.stableCount == 0; 5812 if (!lastRef) { 5813 try { 5814 if (DEBUG_PROVIDER) { 5815 Slog.v(TAG, "releaseProvider: No longer unstable - " 5816 + prc.holder.info.name); 5817 } 5818 ActivityManager.getService().refContentProvider( 5819 prc.holder.connection, 0, -1); 5820 } catch (RemoteException e) { 5821 //do nothing content provider object is dead any way 5822 } 5823 } 5824 } 5825 } 5826 5827 if (lastRef) { 5828 if (!prc.removePending) { 5829 // Schedule the actual remove asynchronously, since we don't know the context 5830 // this will be called in. 5831 // TODO: it would be nice to post a delayed message, so 5832 // if we come back and need the same provider quickly 5833 // we will still have it available. 5834 if (DEBUG_PROVIDER) { 5835 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 5836 + prc.holder.info.name); 5837 } 5838 prc.removePending = true; 5839 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 5840 mH.sendMessage(msg); 5841 } else { 5842 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 5843 } 5844 } 5845 return true; 5846 } 5847 } 5848 5849 final void completeRemoveProvider(ProviderRefCount prc) { 5850 synchronized (mProviderMap) { 5851 if (!prc.removePending) { 5852 // There was a race! Some other client managed to acquire 5853 // the provider before the removal was completed. 5854 // Abort the removal. We will do it later. 5855 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 5856 + "provider still in use"); 5857 return; 5858 } 5859 5860 // More complicated race!! Some client managed to acquire the 5861 // provider and release it before the removal was completed. 5862 // Continue the removal, and abort the next remove message. 5863 prc.removePending = false; 5864 5865 final IBinder jBinder = prc.holder.provider.asBinder(); 5866 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 5867 if (existingPrc == prc) { 5868 mProviderRefCountMap.remove(jBinder); 5869 } 5870 5871 for (int i=mProviderMap.size()-1; i>=0; i--) { 5872 ProviderClientRecord pr = mProviderMap.valueAt(i); 5873 IBinder myBinder = pr.mProvider.asBinder(); 5874 if (myBinder == jBinder) { 5875 mProviderMap.removeAt(i); 5876 } 5877 } 5878 } 5879 5880 try { 5881 if (DEBUG_PROVIDER) { 5882 Slog.v(TAG, "removeProvider: Invoking ActivityManagerService." 5883 + "removeContentProvider(" + prc.holder.info.name + ")"); 5884 } 5885 ActivityManager.getService().removeContentProvider( 5886 prc.holder.connection, false); 5887 } catch (RemoteException e) { 5888 //do nothing content provider object is dead any way 5889 } 5890 } 5891 5892 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 5893 synchronized (mProviderMap) { 5894 handleUnstableProviderDiedLocked(provider, fromClient); 5895 } 5896 } 5897 5898 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 5899 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5900 if (prc != null) { 5901 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 5902 + provider + " " + prc.holder.info.name); 5903 mProviderRefCountMap.remove(provider); 5904 for (int i=mProviderMap.size()-1; i>=0; i--) { 5905 ProviderClientRecord pr = mProviderMap.valueAt(i); 5906 if (pr != null && pr.mProvider.asBinder() == provider) { 5907 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 5908 mProviderMap.removeAt(i); 5909 } 5910 } 5911 5912 if (fromClient) { 5913 // We found out about this due to execution in our client 5914 // code. Tell the activity manager about it now, to ensure 5915 // that the next time we go to do anything with the provider 5916 // it knows it is dead (so we don't race with its death 5917 // notification). 5918 try { 5919 ActivityManager.getService().unstableProviderDied( 5920 prc.holder.connection); 5921 } catch (RemoteException e) { 5922 //do nothing content provider object is dead any way 5923 } 5924 } 5925 } 5926 } 5927 5928 final void appNotRespondingViaProvider(IBinder provider) { 5929 synchronized (mProviderMap) { 5930 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5931 if (prc != null) { 5932 try { 5933 ActivityManager.getService() 5934 .appNotRespondingViaProvider(prc.holder.connection); 5935 } catch (RemoteException e) { 5936 throw e.rethrowFromSystemServer(); 5937 } 5938 } 5939 } 5940 } 5941 5942 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 5943 ContentProvider localProvider, ContentProviderHolder holder) { 5944 final String auths[] = holder.info.authority.split(";"); 5945 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 5946 5947 if (provider != null) { 5948 // If this provider is hosted by the core OS and cannot be upgraded, 5949 // then I guess we're okay doing blocking calls to it. 5950 for (String auth : auths) { 5951 switch (auth) { 5952 case ContactsContract.AUTHORITY: 5953 case CallLog.AUTHORITY: 5954 case CallLog.SHADOW_AUTHORITY: 5955 case BlockedNumberContract.AUTHORITY: 5956 case CalendarContract.AUTHORITY: 5957 case Downloads.Impl.AUTHORITY: 5958 case "telephony": 5959 Binder.allowBlocking(provider.asBinder()); 5960 } 5961 } 5962 } 5963 5964 final ProviderClientRecord pcr = new ProviderClientRecord( 5965 auths, provider, localProvider, holder); 5966 for (String auth : auths) { 5967 final ProviderKey key = new ProviderKey(auth, userId); 5968 final ProviderClientRecord existing = mProviderMap.get(key); 5969 if (existing != null) { 5970 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 5971 + " already published as " + auth); 5972 } else { 5973 mProviderMap.put(key, pcr); 5974 } 5975 } 5976 return pcr; 5977 } 5978 5979 /** 5980 * Installs the provider. 5981 * 5982 * Providers that are local to the process or that come from the system server 5983 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 5984 * Other remote providers are reference counted. The initial reference count 5985 * for all reference counted providers is one. Providers that are not reference 5986 * counted do not have a reference count (at all). 5987 * 5988 * This method detects when a provider has already been installed. When this happens, 5989 * it increments the reference count of the existing provider (if appropriate) 5990 * and returns the existing provider. This can happen due to concurrent 5991 * attempts to acquire the same provider. 5992 */ 5993 private ContentProviderHolder installProvider(Context context, 5994 ContentProviderHolder holder, ProviderInfo info, 5995 boolean noisy, boolean noReleaseNeeded, boolean stable) { 5996 ContentProvider localProvider = null; 5997 IContentProvider provider; 5998 if (holder == null || holder.provider == null) { 5999 if (DEBUG_PROVIDER || noisy) { 6000 Slog.d(TAG, "Loading provider " + info.authority + ": " 6001 + info.name); 6002 } 6003 Context c = null; 6004 ApplicationInfo ai = info.applicationInfo; 6005 if (context.getPackageName().equals(ai.packageName)) { 6006 c = context; 6007 } else if (mInitialApplication != null && 6008 mInitialApplication.getPackageName().equals(ai.packageName)) { 6009 c = mInitialApplication; 6010 } else { 6011 try { 6012 c = context.createPackageContext(ai.packageName, 6013 Context.CONTEXT_INCLUDE_CODE); 6014 } catch (PackageManager.NameNotFoundException e) { 6015 // Ignore 6016 } 6017 } 6018 if (c == null) { 6019 Slog.w(TAG, "Unable to get context for package " + 6020 ai.packageName + 6021 " while loading content provider " + 6022 info.name); 6023 return null; 6024 } 6025 try { 6026 final java.lang.ClassLoader cl = c.getClassLoader(); 6027 localProvider = (ContentProvider)cl. 6028 loadClass(info.name).newInstance(); 6029 provider = localProvider.getIContentProvider(); 6030 if (provider == null) { 6031 Slog.e(TAG, "Failed to instantiate class " + 6032 info.name + " from sourceDir " + 6033 info.applicationInfo.sourceDir); 6034 return null; 6035 } 6036 if (DEBUG_PROVIDER) Slog.v( 6037 TAG, "Instantiating local provider " + info.name); 6038 // XXX Need to create the correct context for this provider. 6039 localProvider.attachInfo(c, info); 6040 } catch (java.lang.Exception e) { 6041 if (!mInstrumentation.onException(null, e)) { 6042 throw new RuntimeException( 6043 "Unable to get provider " + info.name 6044 + ": " + e.toString(), e); 6045 } 6046 return null; 6047 } 6048 } else { 6049 provider = holder.provider; 6050 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 6051 + info.name); 6052 } 6053 6054 ContentProviderHolder retHolder; 6055 6056 synchronized (mProviderMap) { 6057 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 6058 + " / " + info.name); 6059 IBinder jBinder = provider.asBinder(); 6060 if (localProvider != null) { 6061 ComponentName cname = new ComponentName(info.packageName, info.name); 6062 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 6063 if (pr != null) { 6064 if (DEBUG_PROVIDER) { 6065 Slog.v(TAG, "installProvider: lost the race, " 6066 + "using existing local provider"); 6067 } 6068 provider = pr.mProvider; 6069 } else { 6070 holder = new ContentProviderHolder(info); 6071 holder.provider = provider; 6072 holder.noReleaseNeeded = true; 6073 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 6074 mLocalProviders.put(jBinder, pr); 6075 mLocalProvidersByName.put(cname, pr); 6076 } 6077 retHolder = pr.mHolder; 6078 } else { 6079 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 6080 if (prc != null) { 6081 if (DEBUG_PROVIDER) { 6082 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 6083 } 6084 // We need to transfer our new reference to the existing 6085 // ref count, releasing the old one... but only if 6086 // release is needed (that is, it is not running in the 6087 // system process). 6088 if (!noReleaseNeeded) { 6089 incProviderRefLocked(prc, stable); 6090 try { 6091 ActivityManager.getService().removeContentProvider( 6092 holder.connection, stable); 6093 } catch (RemoteException e) { 6094 //do nothing content provider object is dead any way 6095 } 6096 } 6097 } else { 6098 ProviderClientRecord client = installProviderAuthoritiesLocked( 6099 provider, localProvider, holder); 6100 if (noReleaseNeeded) { 6101 prc = new ProviderRefCount(holder, client, 1000, 1000); 6102 } else { 6103 prc = stable 6104 ? new ProviderRefCount(holder, client, 1, 0) 6105 : new ProviderRefCount(holder, client, 0, 1); 6106 } 6107 mProviderRefCountMap.put(jBinder, prc); 6108 } 6109 retHolder = prc.holder; 6110 } 6111 } 6112 return retHolder; 6113 } 6114 6115 private void attach(boolean system) { 6116 sCurrentActivityThread = this; 6117 mSystemThread = system; 6118 if (!system) { 6119 ViewRootImpl.addFirstDrawHandler(new Runnable() { 6120 @Override 6121 public void run() { 6122 ensureJitEnabled(); 6123 } 6124 }); 6125 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 6126 UserHandle.myUserId()); 6127 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 6128 final IActivityManager mgr = ActivityManager.getService(); 6129 try { 6130 mgr.attachApplication(mAppThread); 6131 } catch (RemoteException ex) { 6132 throw ex.rethrowFromSystemServer(); 6133 } 6134 // Watch for getting close to heap limit. 6135 BinderInternal.addGcWatcher(new Runnable() { 6136 @Override public void run() { 6137 if (!mSomeActivitiesChanged) { 6138 return; 6139 } 6140 Runtime runtime = Runtime.getRuntime(); 6141 long dalvikMax = runtime.maxMemory(); 6142 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); 6143 if (dalvikUsed > ((3*dalvikMax)/4)) { 6144 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) 6145 + " total=" + (runtime.totalMemory()/1024) 6146 + " used=" + (dalvikUsed/1024)); 6147 mSomeActivitiesChanged = false; 6148 try { 6149 mgr.releaseSomeActivities(mAppThread); 6150 } catch (RemoteException e) { 6151 throw e.rethrowFromSystemServer(); 6152 } 6153 } 6154 } 6155 }); 6156 } else { 6157 // Don't set application object here -- if the system crashes, 6158 // we can't display an alert, we just want to die die die. 6159 android.ddm.DdmHandleAppName.setAppName("system_process", 6160 UserHandle.myUserId()); 6161 try { 6162 mInstrumentation = new Instrumentation(); 6163 ContextImpl context = ContextImpl.createAppContext( 6164 this, getSystemContext().mPackageInfo); 6165 mInitialApplication = context.mPackageInfo.makeApplication(true, null); 6166 mInitialApplication.onCreate(); 6167 } catch (Exception e) { 6168 throw new RuntimeException( 6169 "Unable to instantiate Application():" + e.toString(), e); 6170 } 6171 } 6172 6173 // add dropbox logging to libcore 6174 DropBox.setReporter(new DropBoxReporter()); 6175 6176 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 6177 @Override 6178 public void onConfigurationChanged(Configuration newConfig) { 6179 synchronized (mResourcesManager) { 6180 // We need to apply this change to the resources 6181 // immediately, because upon returning the view 6182 // hierarchy will be informed about it. 6183 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { 6184 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), 6185 mResourcesManager.getConfiguration().getLocales()); 6186 6187 // This actually changed the resources! Tell 6188 // everyone about it. 6189 if (mPendingConfiguration == null || 6190 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 6191 mPendingConfiguration = newConfig; 6192 6193 sendMessage(H.CONFIGURATION_CHANGED, newConfig); 6194 } 6195 } 6196 } 6197 } 6198 @Override 6199 public void onLowMemory() { 6200 } 6201 @Override 6202 public void onTrimMemory(int level) { 6203 } 6204 }); 6205 } 6206 6207 public static ActivityThread systemMain() { 6208 // The system process on low-memory devices do not get to use hardware 6209 // accelerated drawing, since this can add too much overhead to the 6210 // process. 6211 if (!ActivityManager.isHighEndGfx()) { 6212 ThreadedRenderer.disable(true); 6213 } else { 6214 ThreadedRenderer.enableForegroundTrimming(); 6215 } 6216 ActivityThread thread = new ActivityThread(); 6217 thread.attach(true); 6218 return thread; 6219 } 6220 6221 public final void installSystemProviders(List<ProviderInfo> providers) { 6222 if (providers != null) { 6223 installContentProviders(mInitialApplication, providers); 6224 } 6225 } 6226 6227 public int getIntCoreSetting(String key, int defaultValue) { 6228 synchronized (mResourcesManager) { 6229 if (mCoreSettings != null) { 6230 return mCoreSettings.getInt(key, defaultValue); 6231 } 6232 return defaultValue; 6233 } 6234 } 6235 6236 private static class EventLoggingReporter implements EventLogger.Reporter { 6237 @Override 6238 public void report (int code, Object... list) { 6239 EventLog.writeEvent(code, list); 6240 } 6241 } 6242 6243 private class DropBoxReporter implements DropBox.Reporter { 6244 6245 private DropBoxManager dropBox; 6246 6247 public DropBoxReporter() {} 6248 6249 @Override 6250 public void addData(String tag, byte[] data, int flags) { 6251 ensureInitialized(); 6252 dropBox.addData(tag, data, flags); 6253 } 6254 6255 @Override 6256 public void addText(String tag, String data) { 6257 ensureInitialized(); 6258 dropBox.addText(tag, data); 6259 } 6260 6261 private synchronized void ensureInitialized() { 6262 if (dropBox == null) { 6263 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 6264 } 6265 } 6266 } 6267 6268 public static void main(String[] args) { 6269 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); 6270 SamplingProfilerIntegration.start(); 6271 6272 // CloseGuard defaults to true and can be quite spammy. We 6273 // disable it here, but selectively enable it later (via 6274 // StrictMode) on debug builds, but using DropBox, not logs. 6275 CloseGuard.setEnabled(false); 6276 6277 Environment.initForCurrentUser(); 6278 6279 // Set the reporter for event logging in libcore 6280 EventLogger.setReporter(new EventLoggingReporter()); 6281 6282 // Make sure TrustedCertificateStore looks in the right place for CA certificates 6283 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); 6284 TrustedCertificateStore.setDefaultUserDirectory(configDir); 6285 6286 Process.setArgV0("<pre-initialized>"); 6287 6288 Looper.prepareMainLooper(); 6289 6290 ActivityThread thread = new ActivityThread(); 6291 thread.attach(false); 6292 6293 if (sMainThreadHandler == null) { 6294 sMainThreadHandler = thread.getHandler(); 6295 } 6296 6297 if (false) { 6298 Looper.myLooper().setMessageLogging(new 6299 LogPrinter(Log.DEBUG, "ActivityThread")); 6300 } 6301 6302 // End of event ActivityThreadMain. 6303 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 6304 Looper.loop(); 6305 6306 throw new RuntimeException("Main thread loop unexpectedly exited"); 6307 } 6308 6309 // ------------------ Regular JNI ------------------------ 6310 6311 private native void nDumpGraphicsInfo(FileDescriptor fd); 6312} 6313