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