ActivityThread.java revision 369f509d5688f84d1e5205c79ab919c1bac6c969
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.app; 18 19import android.app.assist.AssistContent; 20import android.app.assist.AssistStructure; 21import android.app.backup.BackupAgent; 22import android.content.BroadcastReceiver; 23import android.content.ComponentCallbacks2; 24import android.content.ComponentName; 25import android.content.ContentProvider; 26import android.content.Context; 27import android.content.IContentProvider; 28import android.content.Intent; 29import android.content.IIntentReceiver; 30import android.content.pm.ActivityInfo; 31import android.content.pm.ApplicationInfo; 32import android.content.pm.IPackageManager; 33import android.content.pm.InstrumentationInfo; 34import android.content.pm.PackageInfo; 35import android.content.pm.PackageManager; 36import android.content.pm.PackageManager.NameNotFoundException; 37import android.content.pm.ProviderInfo; 38import android.content.pm.ServiceInfo; 39import android.content.res.AssetManager; 40import android.content.res.CompatibilityInfo; 41import android.content.res.Configuration; 42import android.content.res.Resources; 43import android.content.res.Resources.Theme; 44import android.database.sqlite.SQLiteDatabase; 45import android.database.sqlite.SQLiteDebug; 46import android.database.sqlite.SQLiteDebug.DbStats; 47import android.graphics.Bitmap; 48import android.graphics.Canvas; 49import android.hardware.display.DisplayManagerGlobal; 50import android.net.ConnectivityManager; 51import android.net.IConnectivityManager; 52import android.net.Network; 53import android.net.Proxy; 54import android.net.ProxyInfo; 55import android.net.Uri; 56import android.os.AsyncTask; 57import android.os.Binder; 58import android.os.Build; 59import android.os.Bundle; 60import android.os.Debug; 61import android.os.DropBoxManager; 62import android.os.Environment; 63import android.os.Handler; 64import android.os.IBinder; 65import android.os.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.TransactionTooLargeException; 79import android.os.UserHandle; 80import android.provider.Settings; 81import android.security.NetworkSecurityPolicy; 82import android.security.net.config.NetworkSecurityConfigProvider; 83import android.util.AndroidRuntimeException; 84import android.util.ArrayMap; 85import android.util.DisplayMetrics; 86import android.util.EventLog; 87import android.util.Log; 88import android.util.LogPrinter; 89import android.util.Pair; 90import android.util.PrintWriterPrinter; 91import android.util.Slog; 92import android.util.SparseIntArray; 93import android.util.SuperNotCalledException; 94import android.view.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 scheduleMultiWindowChanged(IBinder token, boolean inMultiWindow) 1248 throws RemoteException { 1249 sendMessage(H.MULTI_WINDOW_CHANGED, token, inMultiWindow ? 1 : 0); 1250 } 1251 1252 @Override 1253 public void schedulePictureInPictureChanged(IBinder token, boolean inPip) 1254 throws RemoteException { 1255 sendMessage(H.PICTURE_IN_PICTURE_CHANGED, token, inPip ? 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_CHANGED = 152; 1328 public static final int PICTURE_IN_PICTURE_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_CHANGED: return "MULTI_WINDOW_CHANGED"; 1384 case PICTURE_IN_PICTURE_CHANGED: return "PICTURE_IN_PICTURE_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_CHANGED: 1630 handleMultiWindowChanged((IBinder) msg.obj, msg.arg1 == 1); 1631 break; 1632 case PICTURE_IN_PICTURE_CHANGED: 1633 handlePictureInPictureChanged((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 throw ex.rethrowFromSystemServer(); 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 throw e.rethrowFromSystemServer(); 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.getTotalSwappedOutPss() : 2246 memInfo.getTotalSwappedOut(), 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 throw e.rethrowFromSystemServer(); 2597 } 2598 2599 ContextImpl appContext = ContextImpl.createActivityContext( 2600 this, r.packageInfo, displayId, r.overrideConfig); 2601 appContext.setOuterContext(activity); 2602 Context baseContext = appContext; 2603 2604 final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 2605 // For debugging purposes, if the activity's package name contains the value of 2606 // the "debug.use-second-display" system property as a substring, then show 2607 // its content on a secondary display if there is one. 2608 String pkgName = SystemProperties.get("debug.second-display.pkg"); 2609 if (pkgName != null && !pkgName.isEmpty() 2610 && r.packageInfo.mPackageName.contains(pkgName)) { 2611 for (int id : dm.getDisplayIds()) { 2612 if (id != Display.DEFAULT_DISPLAY) { 2613 Display display = 2614 dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id)); 2615 baseContext = appContext.createDisplayContext(display); 2616 break; 2617 } 2618 } 2619 } 2620 return baseContext; 2621 } 2622 2623 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { 2624 // If we are getting ready to gc after going to the background, well 2625 // we are back active so skip it. 2626 unscheduleGcIdler(); 2627 mSomeActivitiesChanged = true; 2628 2629 if (r.profilerInfo != null) { 2630 mProfiler.setProfiler(r.profilerInfo); 2631 mProfiler.startProfiling(); 2632 } 2633 2634 // Make sure we are running with the most recent config. 2635 handleConfigurationChanged(null, null); 2636 2637 if (localLOGV) Slog.v( 2638 TAG, "Handling launch of " + r); 2639 2640 // Initialize before creating the activity 2641 WindowManagerGlobal.initialize(); 2642 2643 Activity a = performLaunchActivity(r, customIntent); 2644 2645 if (a != null) { 2646 r.createdConfig = new Configuration(mConfiguration); 2647 reportSizeConfigurations(r); 2648 Bundle oldState = r.state; 2649 handleResumeActivity(r.token, false, r.isForward, 2650 !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq); 2651 2652 if (!r.activity.mFinished && r.startsNotResumed) { 2653 // The activity manager actually wants this one to start out 2654 // paused, because it needs to be visible but isn't in the 2655 // foreground. We accomplish this by going through the 2656 // normal startup (because activities expect to go through 2657 // onResume() the first time they run, before their window 2658 // is displayed), and then pausing it. However, in this case 2659 // we do -not- need to do the full pause cycle (of freezing 2660 // and such) because the activity manager assumes it can just 2661 // retain the current state it has. 2662 try { 2663 r.activity.mCalled = false; 2664 mInstrumentation.callActivityOnPause(r.activity); 2665 // We need to keep around the original state, in case 2666 // we need to be created again. But we only do this 2667 // for pre-Honeycomb apps, which always save their state 2668 // when pausing, so we can not have them save their state 2669 // when restarting from a paused state. For HC and later, 2670 // we want to (and can) let the state be saved as the normal 2671 // part of stopping the activity. 2672 if (r.isPreHoneycomb()) { 2673 r.state = oldState; 2674 } 2675 if (!r.activity.mCalled) { 2676 throw new SuperNotCalledException( 2677 "Activity " + r.intent.getComponent().toShortString() + 2678 " did not call through to super.onPause()"); 2679 } 2680 2681 } catch (SuperNotCalledException e) { 2682 throw e; 2683 2684 } catch (Exception e) { 2685 if (!mInstrumentation.onException(r.activity, e)) { 2686 throw new RuntimeException( 2687 "Unable to pause activity " 2688 + r.intent.getComponent().toShortString() 2689 + ": " + e.toString(), e); 2690 } 2691 } 2692 r.paused = true; 2693 } 2694 } else { 2695 // If there was an error, for any reason, tell the activity 2696 // manager to stop us. 2697 try { 2698 ActivityManagerNative.getDefault() 2699 .finishActivity(r.token, Activity.RESULT_CANCELED, null, 2700 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 2701 } catch (RemoteException ex) { 2702 throw ex.rethrowFromSystemServer(); 2703 } 2704 } 2705 } 2706 2707 private void reportSizeConfigurations(ActivityClientRecord r) { 2708 Configuration[] configurations = r.activity.getResources().getSizeConfigurations(); 2709 if (configurations == null) { 2710 return; 2711 } 2712 SparseIntArray horizontal = new SparseIntArray(); 2713 SparseIntArray vertical = new SparseIntArray(); 2714 SparseIntArray smallest = new SparseIntArray(); 2715 for (int i = configurations.length - 1; i >= 0; i--) { 2716 Configuration config = configurations[i]; 2717 if (config.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { 2718 vertical.put(config.screenHeightDp, 0); 2719 } 2720 if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) { 2721 horizontal.put(config.screenWidthDp, 0); 2722 } 2723 if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { 2724 smallest.put(config.smallestScreenWidthDp, 0); 2725 } 2726 } 2727 try { 2728 ActivityManagerNative.getDefault().reportSizeConfigurations(r.token, 2729 horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys()); 2730 } catch (RemoteException ex) { 2731 throw ex.rethrowFromSystemServer(); 2732 } 2733 2734 } 2735 2736 private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) { 2737 final int N = intents.size(); 2738 for (int i=0; i<N; i++) { 2739 ReferrerIntent intent = intents.get(i); 2740 intent.setExtrasClassLoader(r.activity.getClassLoader()); 2741 intent.prepareToEnterProcess(); 2742 r.activity.mFragments.noteStateNotSaved(); 2743 mInstrumentation.callActivityOnNewIntent(r.activity, intent); 2744 } 2745 } 2746 2747 public final void performNewIntents(IBinder token, List<ReferrerIntent> intents) { 2748 ActivityClientRecord r = mActivities.get(token); 2749 if (r != null) { 2750 final boolean resumed = !r.paused; 2751 if (resumed) { 2752 r.activity.mTemporaryPause = true; 2753 mInstrumentation.callActivityOnPause(r.activity); 2754 } 2755 deliverNewIntents(r, intents); 2756 if (resumed) { 2757 r.activity.performResume(); 2758 r.activity.mTemporaryPause = false; 2759 } 2760 } 2761 } 2762 2763 private void handleNewIntent(NewIntentData data) { 2764 performNewIntents(data.token, data.intents); 2765 } 2766 2767 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { 2768 if (mLastAssistStructure != null) { 2769 AssistStructure structure = mLastAssistStructure.get(); 2770 if (structure != null) { 2771 structure.clearSendChannel(); 2772 } 2773 } 2774 Bundle data = new Bundle(); 2775 AssistStructure structure = null; 2776 AssistContent content = new AssistContent(); 2777 ActivityClientRecord r = mActivities.get(cmd.activityToken); 2778 Uri referrer = null; 2779 if (r != null) { 2780 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data); 2781 r.activity.onProvideAssistData(data); 2782 referrer = r.activity.onProvideReferrer(); 2783 if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL) { 2784 structure = new AssistStructure(r.activity); 2785 Intent activityIntent = r.activity.getIntent(); 2786 if (activityIntent != null && (r.window == null || 2787 (r.window.getAttributes().flags 2788 & WindowManager.LayoutParams.FLAG_SECURE) == 0)) { 2789 Intent intent = new Intent(activityIntent); 2790 intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION 2791 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)); 2792 intent.removeUnsafeExtras(); 2793 content.setDefaultIntent(intent); 2794 } else { 2795 content.setDefaultIntent(new Intent()); 2796 } 2797 r.activity.onProvideAssistContent(content); 2798 } 2799 } 2800 if (structure == null) { 2801 structure = new AssistStructure(); 2802 } 2803 mLastAssistStructure = new WeakReference<>(structure); 2804 IActivityManager mgr = ActivityManagerNative.getDefault(); 2805 try { 2806 mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer); 2807 } catch (RemoteException e) { 2808 throw e.rethrowFromSystemServer(); 2809 } 2810 } 2811 2812 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 2813 ActivityClientRecord r = mActivities.get(token); 2814 if (r != null) { 2815 r.activity.onTranslucentConversionComplete(drawComplete); 2816 } 2817 } 2818 2819 public void onNewActivityOptions(IBinder token, ActivityOptions options) { 2820 ActivityClientRecord r = mActivities.get(token); 2821 if (r != null) { 2822 r.activity.onNewActivityOptions(options); 2823 } 2824 } 2825 2826 public void handleCancelVisibleBehind(IBinder token) { 2827 ActivityClientRecord r = mActivities.get(token); 2828 if (r != null) { 2829 mSomeActivitiesChanged = true; 2830 final Activity activity = r.activity; 2831 if (activity.mVisibleBehind) { 2832 activity.mCalled = false; 2833 activity.onVisibleBehindCanceled(); 2834 // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed. 2835 if (!activity.mCalled) { 2836 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() + 2837 " did not call through to super.onVisibleBehindCanceled()"); 2838 } 2839 activity.mVisibleBehind = false; 2840 } 2841 } 2842 try { 2843 ActivityManagerNative.getDefault().backgroundResourcesReleased(token); 2844 } catch (RemoteException e) { 2845 throw e.rethrowFromSystemServer(); 2846 } 2847 } 2848 2849 public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) { 2850 ActivityClientRecord r = mActivities.get(token); 2851 if (r != null) { 2852 r.activity.onBackgroundVisibleBehindChanged(visible); 2853 } 2854 } 2855 2856 public void handleInstallProvider(ProviderInfo info) { 2857 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2858 try { 2859 installContentProviders(mInitialApplication, Lists.newArrayList(info)); 2860 } finally { 2861 StrictMode.setThreadPolicy(oldPolicy); 2862 } 2863 } 2864 2865 private void handleEnterAnimationComplete(IBinder token) { 2866 ActivityClientRecord r = mActivities.get(token); 2867 if (r != null) { 2868 r.activity.dispatchEnterAnimationComplete(); 2869 } 2870 } 2871 2872 private void handleStartBinderTracking() { 2873 Binder.enableTracing(); 2874 } 2875 2876 private void handleStopBinderTrackingAndDump(ParcelFileDescriptor fd) { 2877 try { 2878 Binder.disableTracing(); 2879 Binder.getTransactionTracker().writeTracesToFile(fd); 2880 } finally { 2881 IoUtils.closeQuietly(fd); 2882 Binder.getTransactionTracker().clearTraces(); 2883 } 2884 } 2885 2886 private void handleMultiWindowChanged(IBinder token, boolean inMultiWindow) { 2887 final ActivityClientRecord r = mActivities.get(token); 2888 if (r != null) { 2889 r.activity.onMultiWindowChanged(inMultiWindow); 2890 } 2891 } 2892 2893 private void handlePictureInPictureChanged(IBinder token, boolean inPip) { 2894 final ActivityClientRecord r = mActivities.get(token); 2895 if (r != null) { 2896 r.activity.onPictureInPictureChanged(inPip); 2897 } 2898 } 2899 2900 private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) { 2901 final ActivityClientRecord r = mActivities.get(token); 2902 if (r != null) { 2903 r.voiceInteractor = interactor; 2904 r.activity.setVoiceInteractor(interactor); 2905 if (interactor == null) { 2906 r.activity.onLocalVoiceInteractionStopped(); 2907 } else { 2908 r.activity.onLocalVoiceInteractionStarted(); 2909 } 2910 } 2911 } 2912 2913 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); 2914 2915 /** 2916 * Return the Intent that's currently being handled by a 2917 * BroadcastReceiver on this thread, or null if none. 2918 * @hide 2919 */ 2920 public static Intent getIntentBeingBroadcast() { 2921 return sCurrentBroadcastIntent.get(); 2922 } 2923 2924 private void handleReceiver(ReceiverData data) { 2925 // If we are getting ready to gc after going to the background, well 2926 // we are back active so skip it. 2927 unscheduleGcIdler(); 2928 2929 String component = data.intent.getComponent().getClassName(); 2930 2931 LoadedApk packageInfo = getPackageInfoNoCheck( 2932 data.info.applicationInfo, data.compatInfo); 2933 2934 IActivityManager mgr = ActivityManagerNative.getDefault(); 2935 2936 BroadcastReceiver receiver; 2937 try { 2938 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2939 data.intent.setExtrasClassLoader(cl); 2940 data.intent.prepareToEnterProcess(); 2941 data.setExtrasClassLoader(cl); 2942 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance(); 2943 } catch (Exception e) { 2944 if (DEBUG_BROADCAST) Slog.i(TAG, 2945 "Finishing failed broadcast to " + data.intent.getComponent()); 2946 data.sendFinished(mgr); 2947 throw new RuntimeException( 2948 "Unable to instantiate receiver " + component 2949 + ": " + e.toString(), e); 2950 } 2951 2952 try { 2953 Application app = packageInfo.makeApplication(false, mInstrumentation); 2954 2955 if (localLOGV) Slog.v( 2956 TAG, "Performing receive of " + data.intent 2957 + ": app=" + app 2958 + ", appName=" + app.getPackageName() 2959 + ", pkg=" + packageInfo.getPackageName() 2960 + ", comp=" + data.intent.getComponent().toShortString() 2961 + ", dir=" + packageInfo.getAppDir()); 2962 2963 ContextImpl context = (ContextImpl)app.getBaseContext(); 2964 sCurrentBroadcastIntent.set(data.intent); 2965 receiver.setPendingResult(data); 2966 receiver.onReceive(context.getReceiverRestrictedContext(), 2967 data.intent); 2968 } catch (Exception e) { 2969 if (DEBUG_BROADCAST) Slog.i(TAG, 2970 "Finishing failed broadcast to " + data.intent.getComponent()); 2971 data.sendFinished(mgr); 2972 if (!mInstrumentation.onException(receiver, e)) { 2973 throw new RuntimeException( 2974 "Unable to start receiver " + component 2975 + ": " + e.toString(), e); 2976 } 2977 } finally { 2978 sCurrentBroadcastIntent.set(null); 2979 } 2980 2981 if (receiver.getPendingResult() != null) { 2982 data.finish(); 2983 } 2984 } 2985 2986 // Instantiate a BackupAgent and tell it that it's alive 2987 private void handleCreateBackupAgent(CreateBackupAgentData data) { 2988 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); 2989 2990 // Sanity check the requested target package's uid against ours 2991 try { 2992 PackageInfo requestedPackage = getPackageManager().getPackageInfo( 2993 data.appInfo.packageName, 0, UserHandle.myUserId()); 2994 if (requestedPackage.applicationInfo.uid != Process.myUid()) { 2995 Slog.w(TAG, "Asked to instantiate non-matching package " 2996 + data.appInfo.packageName); 2997 return; 2998 } 2999 } catch (RemoteException e) { 3000 throw e.rethrowFromSystemServer(); 3001 } 3002 3003 // no longer idle; we have backup work to do 3004 unscheduleGcIdler(); 3005 3006 // instantiate the BackupAgent class named in the manifest 3007 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 3008 String packageName = packageInfo.mPackageName; 3009 if (packageName == null) { 3010 Slog.d(TAG, "Asked to create backup agent for nonexistent package"); 3011 return; 3012 } 3013 3014 String classname = data.appInfo.backupAgentName; 3015 // full backup operation but no app-supplied agent? use the default implementation 3016 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL 3017 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) { 3018 classname = "android.app.backup.FullBackupAgent"; 3019 } 3020 3021 try { 3022 IBinder binder = null; 3023 BackupAgent agent = mBackupAgents.get(packageName); 3024 if (agent != null) { 3025 // reusing the existing instance 3026 if (DEBUG_BACKUP) { 3027 Slog.v(TAG, "Reusing existing agent instance"); 3028 } 3029 binder = agent.onBind(); 3030 } else { 3031 try { 3032 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname); 3033 3034 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 3035 agent = (BackupAgent) cl.loadClass(classname).newInstance(); 3036 3037 // set up the agent's context 3038 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 3039 context.setOuterContext(agent); 3040 agent.attach(context); 3041 3042 agent.onCreate(); 3043 binder = agent.onBind(); 3044 mBackupAgents.put(packageName, agent); 3045 } catch (Exception e) { 3046 // If this is during restore, fail silently; otherwise go 3047 // ahead and let the user see the crash. 3048 Slog.e(TAG, "Agent threw during creation: " + e); 3049 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE 3050 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) { 3051 throw e; 3052 } 3053 // falling through with 'binder' still null 3054 } 3055 } 3056 3057 // tell the OS that we're live now 3058 try { 3059 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder); 3060 } catch (RemoteException e) { 3061 throw e.rethrowFromSystemServer(); 3062 } 3063 } catch (Exception e) { 3064 throw new RuntimeException("Unable to create BackupAgent " 3065 + classname + ": " + e.toString(), e); 3066 } 3067 } 3068 3069 // Tear down a BackupAgent 3070 private void handleDestroyBackupAgent(CreateBackupAgentData data) { 3071 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data); 3072 3073 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 3074 String packageName = packageInfo.mPackageName; 3075 BackupAgent agent = mBackupAgents.get(packageName); 3076 if (agent != null) { 3077 try { 3078 agent.onDestroy(); 3079 } catch (Exception e) { 3080 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo); 3081 e.printStackTrace(); 3082 } 3083 mBackupAgents.remove(packageName); 3084 } else { 3085 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data); 3086 } 3087 } 3088 3089 private void handleCreateService(CreateServiceData data) { 3090 // If we are getting ready to gc after going to the background, well 3091 // we are back active so skip it. 3092 unscheduleGcIdler(); 3093 3094 LoadedApk packageInfo = getPackageInfoNoCheck( 3095 data.info.applicationInfo, data.compatInfo); 3096 Service service = null; 3097 try { 3098 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 3099 service = (Service) cl.loadClass(data.info.name).newInstance(); 3100 } catch (Exception e) { 3101 if (!mInstrumentation.onException(service, e)) { 3102 throw new RuntimeException( 3103 "Unable to instantiate service " + data.info.name 3104 + ": " + e.toString(), e); 3105 } 3106 } 3107 3108 try { 3109 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 3110 3111 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 3112 context.setOuterContext(service); 3113 3114 Application app = packageInfo.makeApplication(false, mInstrumentation); 3115 service.attach(context, this, data.info.name, data.token, app, 3116 ActivityManagerNative.getDefault()); 3117 service.onCreate(); 3118 mServices.put(data.token, service); 3119 try { 3120 ActivityManagerNative.getDefault().serviceDoneExecuting( 3121 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3122 } catch (RemoteException e) { 3123 throw e.rethrowFromSystemServer(); 3124 } 3125 } catch (Exception e) { 3126 if (!mInstrumentation.onException(service, e)) { 3127 throw new RuntimeException( 3128 "Unable to create service " + data.info.name 3129 + ": " + e.toString(), e); 3130 } 3131 } 3132 } 3133 3134 private void handleBindService(BindServiceData data) { 3135 Service s = mServices.get(data.token); 3136 if (DEBUG_SERVICE) 3137 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); 3138 if (s != null) { 3139 try { 3140 data.intent.setExtrasClassLoader(s.getClassLoader()); 3141 data.intent.prepareToEnterProcess(); 3142 try { 3143 if (!data.rebind) { 3144 IBinder binder = s.onBind(data.intent); 3145 ActivityManagerNative.getDefault().publishService( 3146 data.token, data.intent, binder); 3147 } else { 3148 s.onRebind(data.intent); 3149 ActivityManagerNative.getDefault().serviceDoneExecuting( 3150 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3151 } 3152 ensureJitEnabled(); 3153 } catch (RemoteException ex) { 3154 throw ex.rethrowFromSystemServer(); 3155 } 3156 } catch (Exception e) { 3157 if (!mInstrumentation.onException(s, e)) { 3158 throw new RuntimeException( 3159 "Unable to bind to service " + s 3160 + " with " + data.intent + ": " + e.toString(), e); 3161 } 3162 } 3163 } 3164 } 3165 3166 private void handleUnbindService(BindServiceData data) { 3167 Service s = mServices.get(data.token); 3168 if (s != null) { 3169 try { 3170 data.intent.setExtrasClassLoader(s.getClassLoader()); 3171 data.intent.prepareToEnterProcess(); 3172 boolean doRebind = s.onUnbind(data.intent); 3173 try { 3174 if (doRebind) { 3175 ActivityManagerNative.getDefault().unbindFinished( 3176 data.token, data.intent, doRebind); 3177 } else { 3178 ActivityManagerNative.getDefault().serviceDoneExecuting( 3179 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3180 } 3181 } catch (RemoteException ex) { 3182 throw ex.rethrowFromSystemServer(); 3183 } 3184 } catch (Exception e) { 3185 if (!mInstrumentation.onException(s, e)) { 3186 throw new RuntimeException( 3187 "Unable to unbind to service " + s 3188 + " with " + data.intent + ": " + e.toString(), e); 3189 } 3190 } 3191 } 3192 } 3193 3194 private void handleDumpService(DumpComponentInfo info) { 3195 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3196 try { 3197 Service s = mServices.get(info.token); 3198 if (s != null) { 3199 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 3200 info.fd.getFileDescriptor())); 3201 s.dump(info.fd.getFileDescriptor(), pw, info.args); 3202 pw.flush(); 3203 } 3204 } finally { 3205 IoUtils.closeQuietly(info.fd); 3206 StrictMode.setThreadPolicy(oldPolicy); 3207 } 3208 } 3209 3210 private void handleDumpActivity(DumpComponentInfo info) { 3211 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3212 try { 3213 ActivityClientRecord r = mActivities.get(info.token); 3214 if (r != null && r.activity != null) { 3215 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 3216 info.fd.getFileDescriptor())); 3217 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); 3218 pw.flush(); 3219 } 3220 } finally { 3221 IoUtils.closeQuietly(info.fd); 3222 StrictMode.setThreadPolicy(oldPolicy); 3223 } 3224 } 3225 3226 private void handleDumpProvider(DumpComponentInfo info) { 3227 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3228 try { 3229 ProviderClientRecord r = mLocalProviders.get(info.token); 3230 if (r != null && r.mLocalProvider != null) { 3231 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 3232 info.fd.getFileDescriptor())); 3233 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args); 3234 pw.flush(); 3235 } 3236 } finally { 3237 IoUtils.closeQuietly(info.fd); 3238 StrictMode.setThreadPolicy(oldPolicy); 3239 } 3240 } 3241 3242 private void handleServiceArgs(ServiceArgsData data) { 3243 Service s = mServices.get(data.token); 3244 if (s != null) { 3245 try { 3246 if (data.args != null) { 3247 data.args.setExtrasClassLoader(s.getClassLoader()); 3248 data.args.prepareToEnterProcess(); 3249 } 3250 int res; 3251 if (!data.taskRemoved) { 3252 res = s.onStartCommand(data.args, data.flags, data.startId); 3253 } else { 3254 s.onTaskRemoved(data.args); 3255 res = Service.START_TASK_REMOVED_COMPLETE; 3256 } 3257 3258 QueuedWork.waitToFinish(); 3259 3260 try { 3261 ActivityManagerNative.getDefault().serviceDoneExecuting( 3262 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); 3263 } catch (RemoteException e) { 3264 throw e.rethrowFromSystemServer(); 3265 } 3266 ensureJitEnabled(); 3267 } catch (Exception e) { 3268 if (!mInstrumentation.onException(s, e)) { 3269 throw new RuntimeException( 3270 "Unable to start service " + s 3271 + " with " + data.args + ": " + e.toString(), e); 3272 } 3273 } 3274 } 3275 } 3276 3277 private void handleStopService(IBinder token) { 3278 Service s = mServices.remove(token); 3279 if (s != null) { 3280 try { 3281 if (localLOGV) Slog.v(TAG, "Destroying service " + s); 3282 s.onDestroy(); 3283 Context context = s.getBaseContext(); 3284 if (context instanceof ContextImpl) { 3285 final String who = s.getClassName(); 3286 ((ContextImpl) context).scheduleFinalCleanup(who, "Service"); 3287 } 3288 3289 QueuedWork.waitToFinish(); 3290 3291 try { 3292 ActivityManagerNative.getDefault().serviceDoneExecuting( 3293 token, SERVICE_DONE_EXECUTING_STOP, 0, 0); 3294 } catch (RemoteException e) { 3295 throw e.rethrowFromSystemServer(); 3296 } 3297 } catch (Exception e) { 3298 if (!mInstrumentation.onException(s, e)) { 3299 throw new RuntimeException( 3300 "Unable to stop service " + s 3301 + ": " + e.toString(), e); 3302 } 3303 Slog.i(TAG, "handleStopService: exception for " + token, e); 3304 } 3305 } else { 3306 Slog.i(TAG, "handleStopService: token=" + token + " not found."); 3307 } 3308 //Slog.i(TAG, "Running services: " + mServices); 3309 } 3310 3311 public final ActivityClientRecord performResumeActivity(IBinder token, 3312 boolean clearHide) { 3313 ActivityClientRecord r = mActivities.get(token); 3314 if (localLOGV) Slog.v(TAG, "Performing resume of " + r 3315 + " finished=" + r.activity.mFinished); 3316 if (r != null && !r.activity.mFinished) { 3317 if (clearHide) { 3318 r.hideForNow = false; 3319 r.activity.mStartedActivity = false; 3320 } 3321 try { 3322 r.activity.onStateNotSaved(); 3323 r.activity.mFragments.noteStateNotSaved(); 3324 if (r.pendingIntents != null) { 3325 deliverNewIntents(r, r.pendingIntents); 3326 r.pendingIntents = null; 3327 } 3328 if (r.pendingResults != null) { 3329 deliverResults(r, r.pendingResults); 3330 r.pendingResults = null; 3331 } 3332 r.activity.performResume(); 3333 3334 EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, 3335 UserHandle.myUserId(), r.activity.getComponentName().getClassName()); 3336 3337 r.paused = false; 3338 r.stopped = false; 3339 r.state = null; 3340 r.persistentState = null; 3341 } catch (Exception e) { 3342 if (!mInstrumentation.onException(r.activity, e)) { 3343 throw new RuntimeException( 3344 "Unable to resume activity " 3345 + r.intent.getComponent().toShortString() 3346 + ": " + e.toString(), e); 3347 } 3348 } 3349 } 3350 return r; 3351 } 3352 3353 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) { 3354 if (r.mPreserveWindow && !force) { 3355 return; 3356 } 3357 if (r.mPendingRemoveWindow != null) { 3358 r.mPendingRemoveWindowManager.removeViewImmediate( 3359 r.mPendingRemoveWindow.getDecorView()); 3360 IBinder wtoken = r.mPendingRemoveWindow.getDecorView().getWindowToken(); 3361 if (wtoken != null) { 3362 WindowManagerGlobal.getInstance().closeAll(wtoken, 3363 r.activity.getClass().getName(), "Activity"); 3364 } 3365 } 3366 r.mPendingRemoveWindow = null; 3367 r.mPendingRemoveWindowManager = null; 3368 } 3369 3370 final void handleResumeActivity(IBinder token, 3371 boolean clearHide, boolean isForward, boolean reallyResume, int seq) { 3372 ActivityClientRecord r = mActivities.get(token); 3373 if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) { 3374 return; 3375 } 3376 3377 // If we are getting ready to gc after going to the background, well 3378 // we are back active so skip it. 3379 unscheduleGcIdler(); 3380 mSomeActivitiesChanged = true; 3381 3382 // TODO Push resumeArgs into the activity for consideration 3383 r = performResumeActivity(token, clearHide); 3384 3385 if (r != null) { 3386 final Activity a = r.activity; 3387 3388 if (localLOGV) Slog.v( 3389 TAG, "Resume " + r + " started activity: " + 3390 a.mStartedActivity + ", hideForNow: " + r.hideForNow 3391 + ", finished: " + a.mFinished); 3392 3393 final int forwardBit = isForward ? 3394 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 3395 3396 // If the window hasn't yet been added to the window manager, 3397 // and this guy didn't finish itself or start another activity, 3398 // then go ahead and add the window. 3399 boolean willBeVisible = !a.mStartedActivity; 3400 if (!willBeVisible) { 3401 try { 3402 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible( 3403 a.getActivityToken()); 3404 } catch (RemoteException e) { 3405 throw e.rethrowFromSystemServer(); 3406 } 3407 } 3408 if (r.window == null && !a.mFinished && willBeVisible) { 3409 r.window = r.activity.getWindow(); 3410 View decor = r.window.getDecorView(); 3411 decor.setVisibility(View.INVISIBLE); 3412 ViewManager wm = a.getWindowManager(); 3413 WindowManager.LayoutParams l = r.window.getAttributes(); 3414 a.mDecor = decor; 3415 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 3416 l.softInputMode |= forwardBit; 3417 if (r.mPreserveWindow) { 3418 a.mWindowAdded = true; 3419 r.mPreserveWindow = false; 3420 } 3421 if (a.mVisibleFromClient && !a.mWindowAdded) { 3422 a.mWindowAdded = true; 3423 wm.addView(decor, l); 3424 } 3425 3426 // If the window has already been added, but during resume 3427 // we started another activity, then don't yet make the 3428 // window visible. 3429 } else if (!willBeVisible) { 3430 if (localLOGV) Slog.v( 3431 TAG, "Launch " + r + " mStartedActivity set"); 3432 r.hideForNow = true; 3433 } 3434 3435 // Get rid of anything left hanging around. 3436 cleanUpPendingRemoveWindows(r, false /* force */); 3437 3438 // The window is now visible if it has been added, we are not 3439 // simply finishing, and we are not starting another activity. 3440 if (!r.activity.mFinished && willBeVisible 3441 && r.activity.mDecor != null && !r.hideForNow) { 3442 if (r.newConfig != null) { 3443 r.tmpConfig.setTo(r.newConfig); 3444 if (r.overrideConfig != null) { 3445 r.tmpConfig.updateFrom(r.overrideConfig); 3446 } 3447 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 3448 + r.activityInfo.name + " with newConfig " + r.tmpConfig); 3449 performConfigurationChanged(r.activity, r.tmpConfig, REPORT_TO_ACTIVITY); 3450 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 3451 r.newConfig = null; 3452 } 3453 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 3454 + isForward); 3455 WindowManager.LayoutParams l = r.window.getAttributes(); 3456 if ((l.softInputMode 3457 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 3458 != forwardBit) { 3459 l.softInputMode = (l.softInputMode 3460 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 3461 | forwardBit; 3462 if (r.activity.mVisibleFromClient) { 3463 ViewManager wm = a.getWindowManager(); 3464 View decor = r.window.getDecorView(); 3465 wm.updateViewLayout(decor, l); 3466 } 3467 } 3468 r.activity.mVisibleFromServer = true; 3469 mNumVisibleActivities++; 3470 if (r.activity.mVisibleFromClient) { 3471 r.activity.makeVisible(); 3472 } 3473 } 3474 3475 if (!r.onlyLocalRequest) { 3476 r.nextIdle = mNewActivities; 3477 mNewActivities = r; 3478 if (localLOGV) Slog.v( 3479 TAG, "Scheduling idle handler for " + r); 3480 Looper.myQueue().addIdleHandler(new Idler()); 3481 } 3482 r.onlyLocalRequest = false; 3483 3484 // Tell the activity manager we have resumed. 3485 if (reallyResume) { 3486 try { 3487 ActivityManagerNative.getDefault().activityResumed(token); 3488 } catch (RemoteException ex) { 3489 throw ex.rethrowFromSystemServer(); 3490 } 3491 } 3492 3493 } else { 3494 // If an exception was thrown when trying to resume, then 3495 // just end this activity. 3496 try { 3497 ActivityManagerNative.getDefault() 3498 .finishActivity(token, Activity.RESULT_CANCELED, null, 3499 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 3500 } catch (RemoteException ex) { 3501 throw ex.rethrowFromSystemServer(); 3502 } 3503 } 3504 } 3505 3506 private int mThumbnailWidth = -1; 3507 private int mThumbnailHeight = -1; 3508 private Bitmap mAvailThumbnailBitmap = null; 3509 private Canvas mThumbnailCanvas = null; 3510 3511 private Bitmap createThumbnailBitmap(ActivityClientRecord r) { 3512 Bitmap thumbnail = mAvailThumbnailBitmap; 3513 try { 3514 if (thumbnail == null) { 3515 int w = mThumbnailWidth; 3516 int h; 3517 if (w < 0) { 3518 Resources res = r.activity.getResources(); 3519 int wId = com.android.internal.R.dimen.thumbnail_width; 3520 int hId = com.android.internal.R.dimen.thumbnail_height; 3521 mThumbnailWidth = w = res.getDimensionPixelSize(wId); 3522 mThumbnailHeight = h = res.getDimensionPixelSize(hId); 3523 } else { 3524 h = mThumbnailHeight; 3525 } 3526 3527 // On platforms where we don't want thumbnails, set dims to (0,0) 3528 if ((w > 0) && (h > 0)) { 3529 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 3530 w, h, THUMBNAIL_FORMAT); 3531 thumbnail.eraseColor(0); 3532 } 3533 } 3534 3535 if (thumbnail != null) { 3536 Canvas cv = mThumbnailCanvas; 3537 if (cv == null) { 3538 mThumbnailCanvas = cv = new Canvas(); 3539 } 3540 3541 cv.setBitmap(thumbnail); 3542 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 3543 mAvailThumbnailBitmap = thumbnail; 3544 thumbnail = null; 3545 } 3546 cv.setBitmap(null); 3547 } 3548 3549 } catch (Exception e) { 3550 if (!mInstrumentation.onException(r.activity, e)) { 3551 throw new RuntimeException( 3552 "Unable to create thumbnail of " 3553 + r.intent.getComponent().toShortString() 3554 + ": " + e.toString(), e); 3555 } 3556 thumbnail = null; 3557 } 3558 3559 return thumbnail; 3560 } 3561 3562 private void handlePauseActivity(IBinder token, boolean finished, 3563 boolean userLeaving, int configChanges, boolean dontReport, int seq) { 3564 ActivityClientRecord r = mActivities.get(token); 3565 if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) { 3566 return; 3567 } 3568 if (r != null) { 3569 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 3570 if (userLeaving) { 3571 performUserLeavingActivity(r); 3572 } 3573 3574 r.activity.mConfigChangeFlags |= configChanges; 3575 performPauseActivity(token, finished, r.isPreHoneycomb()); 3576 3577 // Make sure any pending writes are now committed. 3578 if (r.isPreHoneycomb()) { 3579 QueuedWork.waitToFinish(); 3580 } 3581 3582 // Tell the activity manager we have paused. 3583 if (!dontReport) { 3584 try { 3585 ActivityManagerNative.getDefault().activityPaused(token); 3586 } catch (RemoteException ex) { 3587 throw ex.rethrowFromSystemServer(); 3588 } 3589 } 3590 mSomeActivitiesChanged = true; 3591 } 3592 } 3593 3594 final void performUserLeavingActivity(ActivityClientRecord r) { 3595 mInstrumentation.callActivityOnUserLeaving(r.activity); 3596 } 3597 3598 final Bundle performPauseActivity(IBinder token, boolean finished, 3599 boolean saveState) { 3600 ActivityClientRecord r = mActivities.get(token); 3601 return r != null ? performPauseActivity(r, finished, saveState) : null; 3602 } 3603 3604 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 3605 boolean saveState) { 3606 if (r.paused) { 3607 if (r.activity.mFinished) { 3608 // If we are finishing, we won't call onResume() in certain cases. 3609 // So here we likewise don't want to call onPause() if the activity 3610 // isn't resumed. 3611 return null; 3612 } 3613 RuntimeException e = new RuntimeException( 3614 "Performing pause of activity that is not resumed: " 3615 + r.intent.getComponent().toShortString()); 3616 Slog.e(TAG, e.getMessage(), e); 3617 } 3618 if (finished) { 3619 r.activity.mFinished = true; 3620 } 3621 try { 3622 // Next have the activity save its current state and managed dialogs... 3623 if (!r.activity.mFinished && saveState) { 3624 callCallActivityOnSaveInstanceState(r); 3625 } 3626 // Now we are idle. 3627 r.activity.mCalled = false; 3628 mInstrumentation.callActivityOnPause(r.activity); 3629 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), 3630 r.activity.getComponentName().getClassName()); 3631 if (!r.activity.mCalled) { 3632 throw new SuperNotCalledException( 3633 "Activity " + r.intent.getComponent().toShortString() + 3634 " did not call through to super.onPause()"); 3635 } 3636 3637 } catch (SuperNotCalledException e) { 3638 throw e; 3639 3640 } catch (Exception e) { 3641 if (!mInstrumentation.onException(r.activity, e)) { 3642 throw new RuntimeException( 3643 "Unable to pause activity " 3644 + r.intent.getComponent().toShortString() 3645 + ": " + e.toString(), e); 3646 } 3647 } 3648 r.paused = true; 3649 3650 // Notify any outstanding on paused listeners 3651 ArrayList<OnActivityPausedListener> listeners; 3652 synchronized (mOnPauseListeners) { 3653 listeners = mOnPauseListeners.remove(r.activity); 3654 } 3655 int size = (listeners != null ? listeners.size() : 0); 3656 for (int i = 0; i < size; i++) { 3657 listeners.get(i).onPaused(r.activity); 3658 } 3659 3660 return !r.activity.mFinished && saveState ? r.state : null; 3661 } 3662 3663 final void performStopActivity(IBinder token, boolean saveState) { 3664 ActivityClientRecord r = mActivities.get(token); 3665 performStopActivityInner(r, null, false, saveState); 3666 } 3667 3668 private static class StopInfo implements Runnable { 3669 ActivityClientRecord activity; 3670 Bundle state; 3671 PersistableBundle persistentState; 3672 CharSequence description; 3673 3674 @Override public void run() { 3675 // Tell activity manager we have been stopped. 3676 try { 3677 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3678 ActivityManagerNative.getDefault().activityStopped( 3679 activity.token, state, persistentState, description); 3680 } catch (RemoteException ex) { 3681 if (ex instanceof TransactionTooLargeException 3682 && "com.google.android.gms".equals(activity.packageInfo.getPackageName())) { 3683 Log.d(TAG, "STAHP SENDING SO MUCH DATA KTHX: " + ex); 3684 return; 3685 } 3686 3687 throw ex.rethrowFromSystemServer(); 3688 } 3689 } 3690 } 3691 3692 private static final class ProviderRefCount { 3693 public final IActivityManager.ContentProviderHolder holder; 3694 public final ProviderClientRecord client; 3695 public int stableCount; 3696 public int unstableCount; 3697 3698 // When this is set, the stable and unstable ref counts are 0 and 3699 // we have a pending operation scheduled to remove the ref count 3700 // from the activity manager. On the activity manager we are still 3701 // holding an unstable ref, though it is not reflected in the counts 3702 // here. 3703 public boolean removePending; 3704 3705 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder, 3706 ProviderClientRecord inClient, int sCount, int uCount) { 3707 holder = inHolder; 3708 client = inClient; 3709 stableCount = sCount; 3710 unstableCount = uCount; 3711 } 3712 } 3713 3714 /** 3715 * Core implementation of stopping an activity. Note this is a little 3716 * tricky because the server's meaning of stop is slightly different 3717 * than our client -- for the server, stop means to save state and give 3718 * it the result when it is done, but the window may still be visible. 3719 * For the client, we want to call onStop()/onStart() to indicate when 3720 * the activity's UI visibillity changes. 3721 */ 3722 private void performStopActivityInner(ActivityClientRecord r, 3723 StopInfo info, boolean keepShown, boolean saveState) { 3724 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3725 if (r != null) { 3726 if (!keepShown && r.stopped) { 3727 if (r.activity.mFinished) { 3728 // If we are finishing, we won't call onResume() in certain 3729 // cases. So here we likewise don't want to call onStop() 3730 // if the activity isn't resumed. 3731 return; 3732 } 3733 RuntimeException e = new RuntimeException( 3734 "Performing stop of activity that is not resumed: " 3735 + r.intent.getComponent().toShortString()); 3736 Slog.e(TAG, e.getMessage(), e); 3737 } 3738 3739 if (info != null) { 3740 try { 3741 // First create a thumbnail for the activity... 3742 // For now, don't create the thumbnail here; we are 3743 // doing that by doing a screen snapshot. 3744 info.description = r.activity.onCreateDescription(); 3745 } catch (Exception e) { 3746 if (!mInstrumentation.onException(r.activity, e)) { 3747 throw new RuntimeException( 3748 "Unable to save state of activity " 3749 + r.intent.getComponent().toShortString() 3750 + ": " + e.toString(), e); 3751 } 3752 } 3753 } 3754 3755 // Next have the activity save its current state and managed dialogs... 3756 if (!r.activity.mFinished && saveState) { 3757 if (r.state == null) { 3758 callCallActivityOnSaveInstanceState(r); 3759 } 3760 } 3761 3762 if (!keepShown) { 3763 try { 3764 // Now we are idle. 3765 r.activity.performStop(false /*preserveWindow*/); 3766 } catch (Exception e) { 3767 if (!mInstrumentation.onException(r.activity, e)) { 3768 throw new RuntimeException( 3769 "Unable to stop activity " 3770 + r.intent.getComponent().toShortString() 3771 + ": " + e.toString(), e); 3772 } 3773 } 3774 r.stopped = true; 3775 } 3776 3777 r.paused = true; 3778 } 3779 } 3780 3781 private void updateVisibility(ActivityClientRecord r, boolean show) { 3782 View v = r.activity.mDecor; 3783 if (v != null) { 3784 if (show) { 3785 if (!r.activity.mVisibleFromServer) { 3786 r.activity.mVisibleFromServer = true; 3787 mNumVisibleActivities++; 3788 if (r.activity.mVisibleFromClient) { 3789 r.activity.makeVisible(); 3790 } 3791 } 3792 if (r.newConfig != null) { 3793 r.tmpConfig.setTo(r.newConfig); 3794 if (r.overrideConfig != null) { 3795 r.tmpConfig.updateFrom(r.overrideConfig); 3796 } 3797 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 3798 + r.activityInfo.name + " with new config " + r.tmpConfig); 3799 performConfigurationChanged(r.activity, r.tmpConfig, REPORT_TO_ACTIVITY); 3800 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 3801 r.newConfig = null; 3802 } 3803 } else { 3804 if (r.activity.mVisibleFromServer) { 3805 r.activity.mVisibleFromServer = false; 3806 mNumVisibleActivities--; 3807 v.setVisibility(View.INVISIBLE); 3808 } 3809 } 3810 } 3811 } 3812 3813 private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) { 3814 ActivityClientRecord r = mActivities.get(token); 3815 if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) { 3816 return; 3817 } 3818 r.activity.mConfigChangeFlags |= configChanges; 3819 3820 StopInfo info = new StopInfo(); 3821 performStopActivityInner(r, info, show, true); 3822 3823 if (localLOGV) Slog.v( 3824 TAG, "Finishing stop of " + r + ": show=" + show 3825 + " win=" + r.window); 3826 3827 updateVisibility(r, show); 3828 3829 // Make sure any pending writes are now committed. 3830 if (!r.isPreHoneycomb()) { 3831 QueuedWork.waitToFinish(); 3832 } 3833 3834 // Schedule the call to tell the activity manager we have 3835 // stopped. We don't do this immediately, because we want to 3836 // have a chance for any other pending work (in particular memory 3837 // trim requests) to complete before you tell the activity 3838 // manager to proceed and allow us to go fully into the background. 3839 info.activity = r; 3840 info.state = r.state; 3841 info.persistentState = r.persistentState; 3842 mH.post(info); 3843 mSomeActivitiesChanged = true; 3844 } 3845 3846 private static boolean checkAndUpdateLifecycleSeq(int seq, ActivityClientRecord r, 3847 String action) { 3848 if (r == null) { 3849 return true; 3850 } 3851 if (seq < r.lastProcessedSeq) { 3852 if (DEBUG_ORDER) Slog.d(TAG, action + " for " + r + " ignored, because seq=" + seq 3853 + " < mCurrentLifecycleSeq=" + r.lastProcessedSeq); 3854 return false; 3855 } 3856 r.lastProcessedSeq = seq; 3857 return true; 3858 } 3859 3860 final void performRestartActivity(IBinder token) { 3861 ActivityClientRecord r = mActivities.get(token); 3862 if (r.stopped) { 3863 r.activity.performRestart(); 3864 r.stopped = false; 3865 } 3866 } 3867 3868 private void handleWindowVisibility(IBinder token, boolean show) { 3869 ActivityClientRecord r = mActivities.get(token); 3870 3871 if (r == null) { 3872 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 3873 return; 3874 } 3875 3876 if (!show && !r.stopped) { 3877 performStopActivityInner(r, null, show, false); 3878 } else if (show && r.stopped) { 3879 // If we are getting ready to gc after going to the background, well 3880 // we are back active so skip it. 3881 unscheduleGcIdler(); 3882 3883 r.activity.performRestart(); 3884 r.stopped = false; 3885 } 3886 if (r.activity.mDecor != null) { 3887 if (false) Slog.v( 3888 TAG, "Handle window " + r + " visibility: " + show); 3889 updateVisibility(r, show); 3890 } 3891 mSomeActivitiesChanged = true; 3892 } 3893 3894 private void handleSleeping(IBinder token, boolean sleeping) { 3895 ActivityClientRecord r = mActivities.get(token); 3896 3897 if (r == null) { 3898 Log.w(TAG, "handleSleeping: no activity for token " + token); 3899 return; 3900 } 3901 3902 if (sleeping) { 3903 if (!r.stopped && !r.isPreHoneycomb()) { 3904 try { 3905 // Now we are idle. 3906 r.activity.performStop(false /*preserveWindow*/); 3907 } catch (Exception e) { 3908 if (!mInstrumentation.onException(r.activity, e)) { 3909 throw new RuntimeException( 3910 "Unable to stop activity " 3911 + r.intent.getComponent().toShortString() 3912 + ": " + e.toString(), e); 3913 } 3914 } 3915 r.stopped = true; 3916 } 3917 3918 // Make sure any pending writes are now committed. 3919 if (!r.isPreHoneycomb()) { 3920 QueuedWork.waitToFinish(); 3921 } 3922 3923 // Tell activity manager we slept. 3924 try { 3925 ActivityManagerNative.getDefault().activitySlept(r.token); 3926 } catch (RemoteException ex) { 3927 throw ex.rethrowFromSystemServer(); 3928 } 3929 } else { 3930 if (r.stopped && r.activity.mVisibleFromServer) { 3931 r.activity.performRestart(); 3932 r.stopped = false; 3933 } 3934 } 3935 } 3936 3937 private void handleSetCoreSettings(Bundle coreSettings) { 3938 synchronized (mResourcesManager) { 3939 mCoreSettings = coreSettings; 3940 } 3941 onCoreSettingsChange(); 3942 } 3943 3944 private void onCoreSettingsChange() { 3945 boolean debugViewAttributes = 3946 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 3947 if (debugViewAttributes != View.mDebugViewAttributes) { 3948 View.mDebugViewAttributes = debugViewAttributes; 3949 3950 // request all activities to relaunch for the changes to take place 3951 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { 3952 requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false, 3953 false /* preserveWindow */); 3954 } 3955 } 3956 } 3957 3958 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 3959 LoadedApk apk = peekPackageInfo(data.pkg, false); 3960 if (apk != null) { 3961 apk.setCompatibilityInfo(data.info); 3962 } 3963 apk = peekPackageInfo(data.pkg, true); 3964 if (apk != null) { 3965 apk.setCompatibilityInfo(data.info); 3966 } 3967 handleConfigurationChanged(mConfiguration, data.info); 3968 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 3969 } 3970 3971 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 3972 final int N = results.size(); 3973 for (int i=0; i<N; i++) { 3974 ResultInfo ri = results.get(i); 3975 try { 3976 if (ri.mData != null) { 3977 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 3978 ri.mData.prepareToEnterProcess(); 3979 } 3980 if (DEBUG_RESULTS) Slog.v(TAG, 3981 "Delivering result to activity " + r + " : " + ri); 3982 r.activity.dispatchActivityResult(ri.mResultWho, 3983 ri.mRequestCode, ri.mResultCode, ri.mData); 3984 } catch (Exception e) { 3985 if (!mInstrumentation.onException(r.activity, e)) { 3986 throw new RuntimeException( 3987 "Failure delivering result " + ri + " to activity " 3988 + r.intent.getComponent().toShortString() 3989 + ": " + e.toString(), e); 3990 } 3991 } 3992 } 3993 } 3994 3995 private void handleSendResult(ResultData res) { 3996 ActivityClientRecord r = mActivities.get(res.token); 3997 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 3998 if (r != null) { 3999 final boolean resumed = !r.paused; 4000 if (!r.activity.mFinished && r.activity.mDecor != null 4001 && r.hideForNow && resumed) { 4002 // We had hidden the activity because it started another 4003 // one... we have gotten a result back and we are not 4004 // paused, so make sure our window is visible. 4005 updateVisibility(r, true); 4006 } 4007 if (resumed) { 4008 try { 4009 // Now we are idle. 4010 r.activity.mCalled = false; 4011 r.activity.mTemporaryPause = true; 4012 mInstrumentation.callActivityOnPause(r.activity); 4013 if (!r.activity.mCalled) { 4014 throw new SuperNotCalledException( 4015 "Activity " + r.intent.getComponent().toShortString() 4016 + " did not call through to super.onPause()"); 4017 } 4018 } catch (SuperNotCalledException e) { 4019 throw e; 4020 } catch (Exception e) { 4021 if (!mInstrumentation.onException(r.activity, e)) { 4022 throw new RuntimeException( 4023 "Unable to pause activity " 4024 + r.intent.getComponent().toShortString() 4025 + ": " + e.toString(), e); 4026 } 4027 } 4028 } 4029 deliverResults(r, res.results); 4030 if (resumed) { 4031 r.activity.performResume(); 4032 r.activity.mTemporaryPause = false; 4033 } 4034 } 4035 } 4036 4037 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 4038 return performDestroyActivity(token, finishing, 0, false); 4039 } 4040 4041 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 4042 int configChanges, boolean getNonConfigInstance) { 4043 ActivityClientRecord r = mActivities.get(token); 4044 Class<? extends Activity> activityClass = null; 4045 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 4046 if (r != null) { 4047 activityClass = r.activity.getClass(); 4048 r.activity.mConfigChangeFlags |= configChanges; 4049 if (finishing) { 4050 r.activity.mFinished = true; 4051 } 4052 if (!r.paused) { 4053 try { 4054 r.activity.mCalled = false; 4055 mInstrumentation.callActivityOnPause(r.activity); 4056 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), 4057 r.activity.getComponentName().getClassName()); 4058 if (!r.activity.mCalled) { 4059 throw new SuperNotCalledException( 4060 "Activity " + safeToComponentShortString(r.intent) 4061 + " did not call through to super.onPause()"); 4062 } 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 pause activity " 4069 + safeToComponentShortString(r.intent) 4070 + ": " + e.toString(), e); 4071 } 4072 } 4073 r.paused = true; 4074 } 4075 if (!r.stopped) { 4076 try { 4077 r.activity.performStop(r.mPreserveWindow); 4078 } catch (SuperNotCalledException e) { 4079 throw e; 4080 } catch (Exception e) { 4081 if (!mInstrumentation.onException(r.activity, e)) { 4082 throw new RuntimeException( 4083 "Unable to stop activity " 4084 + safeToComponentShortString(r.intent) 4085 + ": " + e.toString(), e); 4086 } 4087 } 4088 r.stopped = true; 4089 } 4090 if (getNonConfigInstance) { 4091 try { 4092 r.lastNonConfigurationInstances 4093 = r.activity.retainNonConfigurationInstances(); 4094 } catch (Exception e) { 4095 if (!mInstrumentation.onException(r.activity, e)) { 4096 throw new RuntimeException( 4097 "Unable to retain activity " 4098 + r.intent.getComponent().toShortString() 4099 + ": " + e.toString(), e); 4100 } 4101 } 4102 } 4103 try { 4104 r.activity.mCalled = false; 4105 mInstrumentation.callActivityOnDestroy(r.activity); 4106 if (!r.activity.mCalled) { 4107 throw new SuperNotCalledException( 4108 "Activity " + safeToComponentShortString(r.intent) + 4109 " did not call through to super.onDestroy()"); 4110 } 4111 if (r.window != null) { 4112 r.window.closeAllPanels(); 4113 } 4114 } catch (SuperNotCalledException e) { 4115 throw e; 4116 } catch (Exception e) { 4117 if (!mInstrumentation.onException(r.activity, e)) { 4118 throw new RuntimeException( 4119 "Unable to destroy activity " + safeToComponentShortString(r.intent) 4120 + ": " + e.toString(), e); 4121 } 4122 } 4123 } 4124 mActivities.remove(token); 4125 StrictMode.decrementExpectedActivityCount(activityClass); 4126 return r; 4127 } 4128 4129 private static String safeToComponentShortString(Intent intent) { 4130 ComponentName component = intent.getComponent(); 4131 return component == null ? "[Unknown]" : component.toShortString(); 4132 } 4133 4134 private void handleDestroyActivity(IBinder token, boolean finishing, 4135 int configChanges, boolean getNonConfigInstance) { 4136 ActivityClientRecord r = performDestroyActivity(token, finishing, 4137 configChanges, getNonConfigInstance); 4138 if (r != null) { 4139 cleanUpPendingRemoveWindows(r, finishing); 4140 WindowManager wm = r.activity.getWindowManager(); 4141 View v = r.activity.mDecor; 4142 if (v != null) { 4143 if (r.activity.mVisibleFromServer) { 4144 mNumVisibleActivities--; 4145 } 4146 IBinder wtoken = v.getWindowToken(); 4147 if (r.activity.mWindowAdded) { 4148 if (r.onlyLocalRequest || r.mPreserveWindow) { 4149 // Hold off on removing this until the new activity's 4150 // window is being added. 4151 r.mPendingRemoveWindow = r.window; 4152 r.mPendingRemoveWindowManager = wm; 4153 if (r.mPreserveWindow) { 4154 // We can only keep the part of the view hierarchy that we control, 4155 // everything else must be removed, because it might not be able to 4156 // behave properly when activity is relaunching. 4157 r.window.clearContentView(); 4158 } 4159 } else { 4160 wm.removeViewImmediate(v); 4161 } 4162 } 4163 if (wtoken != null && r.mPendingRemoveWindow == null) { 4164 WindowManagerGlobal.getInstance().closeAll(wtoken, 4165 r.activity.getClass().getName(), "Activity"); 4166 } 4167 r.activity.mDecor = null; 4168 } 4169 if (r.mPendingRemoveWindow == null) { 4170 // If we are delaying the removal of the activity window, then 4171 // we can't clean up all windows here. Note that we can't do 4172 // so later either, which means any windows that aren't closed 4173 // by the app will leak. Well we try to warning them a lot 4174 // about leaking windows, because that is a bug, so if they are 4175 // using this recreate facility then they get to live with leaks. 4176 WindowManagerGlobal.getInstance().closeAll(token, 4177 r.activity.getClass().getName(), "Activity"); 4178 } 4179 4180 // Mocked out contexts won't be participating in the normal 4181 // process lifecycle, but if we're running with a proper 4182 // ApplicationContext we need to have it tear down things 4183 // cleanly. 4184 Context c = r.activity.getBaseContext(); 4185 if (c instanceof ContextImpl) { 4186 ((ContextImpl) c).scheduleFinalCleanup( 4187 r.activity.getClass().getName(), "Activity"); 4188 } 4189 } 4190 if (finishing) { 4191 try { 4192 ActivityManagerNative.getDefault().activityDestroyed(token); 4193 } catch (RemoteException ex) { 4194 throw ex.rethrowFromSystemServer(); 4195 } 4196 } 4197 mSomeActivitiesChanged = true; 4198 } 4199 4200 /** 4201 * @param preserveWindow Whether the activity should try to reuse the window it created, 4202 * including the decor view after the relaunch. 4203 */ 4204 public final void requestRelaunchActivity(IBinder token, 4205 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 4206 int configChanges, boolean notResumed, Configuration config, 4207 Configuration overrideConfig, boolean fromServer, boolean preserveWindow) { 4208 ActivityClientRecord target = null; 4209 4210 synchronized (mResourcesManager) { 4211 for (int i=0; i<mRelaunchingActivities.size(); i++) { 4212 ActivityClientRecord r = mRelaunchingActivities.get(i); 4213 if (r.token == token) { 4214 target = r; 4215 if (pendingResults != null) { 4216 if (r.pendingResults != null) { 4217 r.pendingResults.addAll(pendingResults); 4218 } else { 4219 r.pendingResults = pendingResults; 4220 } 4221 } 4222 if (pendingNewIntents != null) { 4223 if (r.pendingIntents != null) { 4224 r.pendingIntents.addAll(pendingNewIntents); 4225 } else { 4226 r.pendingIntents = pendingNewIntents; 4227 } 4228 } 4229 4230 // For each relaunch request, activity manager expects an answer 4231 if (!r.onlyLocalRequest && fromServer) { 4232 try { 4233 ActivityManagerNative.getDefault().activityRelaunched(token); 4234 } catch (RemoteException e) { 4235 throw e.rethrowFromSystemServer(); 4236 } 4237 } 4238 break; 4239 } 4240 } 4241 4242 if (target == null) { 4243 target = new ActivityClientRecord(); 4244 target.token = token; 4245 target.pendingResults = pendingResults; 4246 target.pendingIntents = pendingNewIntents; 4247 target.mPreserveWindow = preserveWindow; 4248 if (!fromServer) { 4249 ActivityClientRecord existing = mActivities.get(token); 4250 if (existing != null) { 4251 target.startsNotResumed = existing.paused; 4252 target.overrideConfig = existing.overrideConfig; 4253 } 4254 target.onlyLocalRequest = true; 4255 } 4256 mRelaunchingActivities.add(target); 4257 sendMessage(H.RELAUNCH_ACTIVITY, target); 4258 } 4259 4260 if (fromServer) { 4261 target.startsNotResumed = notResumed; 4262 target.onlyLocalRequest = false; 4263 } 4264 if (config != null) { 4265 target.createdConfig = config; 4266 } 4267 if (overrideConfig != null) { 4268 target.overrideConfig = overrideConfig; 4269 } 4270 target.pendingConfigChanges |= configChanges; 4271 target.relaunchSeq = getLifecycleSeq(); 4272 } 4273 if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this 4274 + " operation received seq: " + target.relaunchSeq); 4275 } 4276 4277 private void handleRelaunchActivity(ActivityClientRecord tmp) { 4278 // If we are getting ready to gc after going to the background, well 4279 // we are back active so skip it. 4280 unscheduleGcIdler(); 4281 mSomeActivitiesChanged = true; 4282 4283 Configuration changedConfig = null; 4284 int configChanges = 0; 4285 4286 // First: make sure we have the most recent configuration and most 4287 // recent version of the activity, or skip it if some previous call 4288 // had taken a more recent version. 4289 synchronized (mResourcesManager) { 4290 int N = mRelaunchingActivities.size(); 4291 IBinder token = tmp.token; 4292 tmp = null; 4293 for (int i=0; i<N; i++) { 4294 ActivityClientRecord r = mRelaunchingActivities.get(i); 4295 if (r.token == token) { 4296 tmp = r; 4297 configChanges |= tmp.pendingConfigChanges; 4298 mRelaunchingActivities.remove(i); 4299 i--; 4300 N--; 4301 } 4302 } 4303 4304 if (tmp == null) { 4305 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 4306 return; 4307 } 4308 4309 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4310 + tmp.token + " with configChanges=0x" 4311 + Integer.toHexString(configChanges)); 4312 4313 if (mPendingConfiguration != null) { 4314 changedConfig = mPendingConfiguration; 4315 mPendingConfiguration = null; 4316 } 4317 } 4318 4319 if (tmp.lastProcessedSeq > tmp.relaunchSeq) { 4320 Slog.wtf(TAG, "For some reason target: " + tmp + " has lower sequence: " 4321 + tmp.relaunchSeq + " than current sequence: " + tmp.lastProcessedSeq); 4322 } else { 4323 tmp.lastProcessedSeq = tmp.relaunchSeq; 4324 } 4325 if (tmp.createdConfig != null) { 4326 // If the activity manager is passing us its current config, 4327 // assume that is really what we want regardless of what we 4328 // may have pending. 4329 if (mConfiguration == null 4330 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 4331 && mConfiguration.diff(tmp.createdConfig) != 0)) { 4332 if (changedConfig == null 4333 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 4334 changedConfig = tmp.createdConfig; 4335 } 4336 } 4337 } 4338 4339 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4340 + tmp.token + ": changedConfig=" + changedConfig); 4341 4342 // If there was a pending configuration change, execute it first. 4343 if (changedConfig != null) { 4344 mCurDefaultDisplayDpi = changedConfig.densityDpi; 4345 updateDefaultDensity(); 4346 handleConfigurationChanged(changedConfig, null); 4347 } 4348 4349 ActivityClientRecord r = mActivities.get(tmp.token); 4350 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 4351 if (r == null) { 4352 if (!tmp.onlyLocalRequest) { 4353 try { 4354 ActivityManagerNative.getDefault().activityRelaunched(tmp.token); 4355 } catch (RemoteException e) { 4356 throw e.rethrowFromSystemServer(); 4357 } 4358 } 4359 return; 4360 } 4361 4362 r.activity.mConfigChangeFlags |= configChanges; 4363 r.onlyLocalRequest = tmp.onlyLocalRequest; 4364 r.mPreserveWindow = tmp.mPreserveWindow; 4365 r.lastProcessedSeq = tmp.lastProcessedSeq; 4366 r.relaunchSeq = tmp.relaunchSeq; 4367 Intent currentIntent = r.activity.mIntent; 4368 4369 r.activity.mChangingConfigurations = true; 4370 4371 // If we are preserving the main window across relaunches we would also like to preserve 4372 // the children. However the client side view system does not support preserving 4373 // the child views so we notify the window manager to expect these windows to 4374 // be replaced and defer requests to destroy or hide them. This way we can achieve 4375 // visual continuity. It's important that we do this here prior to pause and destroy 4376 // as that is when we may hide or remove the child views. 4377 try { 4378 if (r.mPreserveWindow) { 4379 WindowManagerGlobal.getWindowSession().prepareToReplaceChildren(r.token); 4380 } 4381 } catch (RemoteException e) { 4382 throw e.rethrowFromSystemServer(); 4383 } 4384 4385 4386 // Need to ensure state is saved. 4387 if (!r.paused) { 4388 performPauseActivity(r.token, false, r.isPreHoneycomb()); 4389 } 4390 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 4391 callCallActivityOnSaveInstanceState(r); 4392 } 4393 4394 handleDestroyActivity(r.token, false, configChanges, true); 4395 4396 r.activity = null; 4397 r.window = null; 4398 r.hideForNow = false; 4399 r.nextIdle = null; 4400 // Merge any pending results and pending intents; don't just replace them 4401 if (tmp.pendingResults != null) { 4402 if (r.pendingResults == null) { 4403 r.pendingResults = tmp.pendingResults; 4404 } else { 4405 r.pendingResults.addAll(tmp.pendingResults); 4406 } 4407 } 4408 if (tmp.pendingIntents != null) { 4409 if (r.pendingIntents == null) { 4410 r.pendingIntents = tmp.pendingIntents; 4411 } else { 4412 r.pendingIntents.addAll(tmp.pendingIntents); 4413 } 4414 } 4415 r.startsNotResumed = tmp.startsNotResumed; 4416 r.overrideConfig = tmp.overrideConfig; 4417 4418 handleLaunchActivity(r, currentIntent); 4419 4420 if (!tmp.onlyLocalRequest) { 4421 try { 4422 ActivityManagerNative.getDefault().activityRelaunched(r.token); 4423 if (r.window != null) { 4424 r.window.reportActivityRelaunched(); 4425 } 4426 } catch (RemoteException e) { 4427 throw e.rethrowFromSystemServer(); 4428 } 4429 } 4430 } 4431 4432 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) { 4433 r.state = new Bundle(); 4434 r.state.setAllowFds(false); 4435 if (r.isPersistable()) { 4436 r.persistentState = new PersistableBundle(); 4437 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, 4438 r.persistentState); 4439 } else { 4440 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 4441 } 4442 } 4443 4444 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 4445 boolean allActivities, Configuration newConfig) { 4446 ArrayList<ComponentCallbacks2> callbacks 4447 = new ArrayList<ComponentCallbacks2>(); 4448 4449 synchronized (mResourcesManager) { 4450 final int NAPP = mAllApplications.size(); 4451 for (int i=0; i<NAPP; i++) { 4452 callbacks.add(mAllApplications.get(i)); 4453 } 4454 final int NACT = mActivities.size(); 4455 for (int i=0; i<NACT; i++) { 4456 ActivityClientRecord ar = mActivities.valueAt(i); 4457 Activity a = ar.activity; 4458 if (a != null) { 4459 Configuration thisConfig = applyConfigCompatMainThread( 4460 mCurDefaultDisplayDpi, newConfig, 4461 ar.packageInfo.getCompatibilityInfo()); 4462 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 4463 // If the activity is currently resumed, its configuration 4464 // needs to change right now. 4465 callbacks.add(a); 4466 } else if (thisConfig != null) { 4467 // Otherwise, we will tell it about the change 4468 // the next time it is resumed or shown. Note that 4469 // the activity manager may, before then, decide the 4470 // activity needs to be destroyed to handle its new 4471 // configuration. 4472 if (DEBUG_CONFIGURATION) { 4473 Slog.v(TAG, "Setting activity " 4474 + ar.activityInfo.name + " newConfig=" + thisConfig); 4475 } 4476 ar.newConfig = thisConfig; 4477 } 4478 } 4479 } 4480 final int NSVC = mServices.size(); 4481 for (int i=0; i<NSVC; i++) { 4482 callbacks.add(mServices.valueAt(i)); 4483 } 4484 } 4485 synchronized (mProviderMap) { 4486 final int NPRV = mLocalProviders.size(); 4487 for (int i=0; i<NPRV; i++) { 4488 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 4489 } 4490 } 4491 4492 return callbacks; 4493 } 4494 4495 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config, 4496 boolean reportToActivity) { 4497 // Only for Activity objects, check that they actually call up to their 4498 // superclass implementation. ComponentCallbacks2 is an interface, so 4499 // we check the runtime type and act accordingly. 4500 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 4501 if (activity != null) { 4502 activity.mCalled = false; 4503 } 4504 4505 boolean shouldChangeConfig = false; 4506 if ((activity == null) || (activity.mCurrentConfig == null)) { 4507 shouldChangeConfig = true; 4508 } else { 4509 4510 // If the new config is the same as the config this Activity 4511 // is already running with then don't bother calling 4512 // onConfigurationChanged 4513 int diff = activity.mCurrentConfig.diff(config); 4514 if (diff != 0) { 4515 // If this activity doesn't handle any of the config changes then don't bother 4516 // calling onConfigurationChanged as we're going to destroy it. 4517 // Except in the case where the configuration changed on the activity manager side, 4518 // but wasn't big enough to cause a resource change so the activity wasn't destroyed. 4519 // In this case we still want to change the configuration of the activity but not 4520 // report it to the app. 4521 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0 4522 || !reportToActivity) { 4523 shouldChangeConfig = true; 4524 } 4525 } 4526 } 4527 4528 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb 4529 + ": shouldChangeConfig=" + shouldChangeConfig); 4530 if (shouldChangeConfig) { 4531 if (reportToActivity) { 4532 cb.onConfigurationChanged(config); 4533 } 4534 4535 if (activity != null) { 4536 if (reportToActivity && !activity.mCalled) { 4537 throw new SuperNotCalledException( 4538 "Activity " + activity.getLocalClassName() + 4539 " did not call through to super.onConfigurationChanged()"); 4540 } 4541 activity.mConfigChangeFlags = 0; 4542 activity.mCurrentConfig = new Configuration(config); 4543 } 4544 } 4545 } 4546 4547 public final void applyConfigurationToResources(Configuration config) { 4548 synchronized (mResourcesManager) { 4549 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 4550 } 4551 } 4552 4553 final Configuration applyCompatConfiguration(int displayDensity) { 4554 Configuration config = mConfiguration; 4555 if (mCompatConfiguration == null) { 4556 mCompatConfiguration = new Configuration(); 4557 } 4558 mCompatConfiguration.setTo(mConfiguration); 4559 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) { 4560 config = mCompatConfiguration; 4561 } 4562 return config; 4563 } 4564 4565 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 4566 4567 int configDiff = 0; 4568 4569 synchronized (mResourcesManager) { 4570 if (mPendingConfiguration != null) { 4571 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 4572 config = mPendingConfiguration; 4573 mCurDefaultDisplayDpi = config.densityDpi; 4574 updateDefaultDensity(); 4575 } 4576 mPendingConfiguration = null; 4577 } 4578 4579 if (config == null) { 4580 return; 4581 } 4582 4583 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 4584 + config); 4585 4586 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 4587 4588 if (mConfiguration == null) { 4589 mConfiguration = new Configuration(); 4590 } 4591 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 4592 return; 4593 } 4594 4595 configDiff = mConfiguration.updateFrom(config); 4596 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 4597 4598 final Theme systemTheme = getSystemContext().getTheme(); 4599 if ((systemTheme.getChangingConfigurations() & configDiff) != 0) { 4600 systemTheme.rebase(); 4601 } 4602 } 4603 4604 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 4605 4606 freeTextLayoutCachesIfNeeded(configDiff); 4607 4608 if (callbacks != null) { 4609 final int N = callbacks.size(); 4610 for (int i=0; i<N; i++) { 4611 performConfigurationChanged(callbacks.get(i), config, REPORT_TO_ACTIVITY); 4612 } 4613 } 4614 } 4615 4616 static void freeTextLayoutCachesIfNeeded(int configDiff) { 4617 if (configDiff != 0) { 4618 // Ask text layout engine to free its caches if there is a locale change 4619 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 4620 if (hasLocaleConfigChange) { 4621 Canvas.freeTextLayoutCaches(); 4622 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 4623 } 4624 } 4625 } 4626 4627 final void handleActivityConfigurationChanged(ActivityConfigChangeData data, 4628 boolean reportToActivity) { 4629 ActivityClientRecord r = mActivities.get(data.activityToken); 4630 if (r == null || r.activity == null) { 4631 return; 4632 } 4633 4634 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 4635 + r.activityInfo.name + ", with callback=" + reportToActivity); 4636 4637 r.tmpConfig.setTo(mCompatConfiguration); 4638 if (data.overrideConfig != null) { 4639 r.overrideConfig = data.overrideConfig; 4640 r.tmpConfig.updateFrom(data.overrideConfig); 4641 } 4642 performConfigurationChanged(r.activity, r.tmpConfig, reportToActivity); 4643 4644 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); 4645 4646 mSomeActivitiesChanged = true; 4647 } 4648 4649 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 4650 if (start) { 4651 try { 4652 switch (profileType) { 4653 default: 4654 mProfiler.setProfiler(profilerInfo); 4655 mProfiler.startProfiling(); 4656 break; 4657 } 4658 } catch (RuntimeException e) { 4659 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile 4660 + " -- can the process access this path?"); 4661 } finally { 4662 try { 4663 profilerInfo.profileFd.close(); 4664 } catch (IOException e) { 4665 Slog.w(TAG, "Failure closing profile fd", e); 4666 } 4667 } 4668 } else { 4669 switch (profileType) { 4670 default: 4671 mProfiler.stopProfiling(); 4672 break; 4673 } 4674 } 4675 } 4676 4677 /** 4678 * Public entrypoint to stop profiling. This is required to end profiling when the app crashes, 4679 * so that profiler data won't be lost. 4680 * 4681 * @hide 4682 */ 4683 public void stopProfiling() { 4684 mProfiler.stopProfiling(); 4685 } 4686 4687 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 4688 if (managed) { 4689 try { 4690 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 4691 } catch (IOException e) { 4692 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 4693 + " -- can the process access this path?"); 4694 } finally { 4695 try { 4696 dhd.fd.close(); 4697 } catch (IOException e) { 4698 Slog.w(TAG, "Failure closing profile fd", e); 4699 } 4700 } 4701 } else { 4702 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 4703 } 4704 try { 4705 ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path); 4706 } catch (RemoteException e) { 4707 throw e.rethrowFromSystemServer(); 4708 } 4709 } 4710 4711 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 4712 boolean hasPkgInfo = false; 4713 if (packages != null) { 4714 synchronized (mResourcesManager) { 4715 for (int i=packages.length-1; i>=0; i--) { 4716 //Slog.i(TAG, "Cleaning old package: " + packages[i]); 4717 if (!hasPkgInfo) { 4718 WeakReference<LoadedApk> ref; 4719 ref = mPackages.get(packages[i]); 4720 if (ref != null && ref.get() != null) { 4721 hasPkgInfo = true; 4722 } else { 4723 ref = mResourcePackages.get(packages[i]); 4724 if (ref != null && ref.get() != null) { 4725 hasPkgInfo = true; 4726 } 4727 } 4728 } 4729 mPackages.remove(packages[i]); 4730 mResourcePackages.remove(packages[i]); 4731 } 4732 } 4733 } 4734 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, 4735 hasPkgInfo); 4736 } 4737 4738 final void handleLowMemory() { 4739 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4740 4741 final int N = callbacks.size(); 4742 for (int i=0; i<N; i++) { 4743 callbacks.get(i).onLowMemory(); 4744 } 4745 4746 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4747 if (Process.myUid() != Process.SYSTEM_UID) { 4748 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4749 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4750 } 4751 4752 // Ask graphics to free up as much as possible (font/image caches) 4753 Canvas.freeCaches(); 4754 4755 // Ask text layout engine to free also as much as possible 4756 Canvas.freeTextLayoutCaches(); 4757 4758 BinderInternal.forceGc("mem"); 4759 } 4760 4761 final void handleTrimMemory(int level) { 4762 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4763 4764 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4765 4766 final int N = callbacks.size(); 4767 for (int i = 0; i < N; i++) { 4768 callbacks.get(i).onTrimMemory(level); 4769 } 4770 4771 WindowManagerGlobal.getInstance().trimMemory(level); 4772 } 4773 4774 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4775 if (Process.isIsolated()) { 4776 // Isolated processes aren't going to do UI. 4777 return; 4778 } 4779 try { 4780 int uid = Process.myUid(); 4781 String[] packages = getPackageManager().getPackagesForUid(uid); 4782 4783 // If there are several packages in this application we won't 4784 // initialize the graphics disk caches 4785 if (packages != null && packages.length == 1) { 4786 ThreadedRenderer.setupDiskCache(cacheDir); 4787 RenderScriptCacheDir.setupDiskCache(cacheDir); 4788 } 4789 } catch (RemoteException e) { 4790 throw e.rethrowFromSystemServer(); 4791 } 4792 } 4793 4794 // Keep in sync with installd (frameworks/native/cmds/installd/commands.cpp). 4795 private static File getPrimaryProfileFile(String packageName) { 4796 return new File("/data/misc/profiles/cur/" + UserHandle.myUserId() + 4797 "/" + packageName + "/primary.prof"); 4798 } 4799 4800 private static void setupJitProfileSupport(LoadedApk loadedApk, File cacheDir) { 4801 if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) { 4802 return; 4803 } 4804 final ApplicationInfo appInfo = loadedApk.getApplicationInfo(); 4805 final List<String> codePaths = new ArrayList<>(); 4806 if ((appInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) { 4807 codePaths.add(appInfo.sourceDir); 4808 } 4809 if (appInfo.splitSourceDirs != null) { 4810 Collections.addAll(codePaths, appInfo.splitSourceDirs); 4811 } 4812 4813 if (codePaths.isEmpty()) { 4814 // If there are no code paths there's no need to setup a profile file and register with 4815 // the runtime, 4816 return; 4817 } 4818 4819 final File profileFile = getPrimaryProfileFile(loadedApk.mPackageName); 4820 if (!profileFile.exists()) { 4821 FileDescriptor fd = null; 4822 try { 4823 final int permissions = 0600; // read-write for user. 4824 fd = Os.open(profileFile.getAbsolutePath(), OsConstants.O_CREAT, permissions); 4825 Os.fchmod(fd, permissions); 4826 Os.fchown(fd, appInfo.uid, appInfo.uid); 4827 } catch (ErrnoException e) { 4828 Log.v(TAG, "Unable to create jit profile file " + profileFile, e); 4829 try { 4830 Os.unlink(profileFile.getAbsolutePath()); 4831 } catch (ErrnoException unlinkErr) { 4832 Log.v(TAG, "Unable to unlink jit profile file " + profileFile, unlinkErr); 4833 } 4834 return; 4835 } finally { 4836 IoUtils.closeQuietly(fd); 4837 } 4838 } 4839 4840 VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), appInfo.dataDir, 4841 codePaths.toArray(new String[codePaths.size()])); 4842 } 4843 4844 private void updateDefaultDensity() { 4845 final int densityDpi = mCurDefaultDisplayDpi; 4846 if (!mDensityCompatMode 4847 && densityDpi != Configuration.DENSITY_DPI_UNDEFINED 4848 && densityDpi != DisplayMetrics.DENSITY_DEVICE) { 4849 DisplayMetrics.DENSITY_DEVICE = densityDpi; 4850 Bitmap.setDefaultDensity(densityDpi); 4851 } 4852 } 4853 4854 private void handleBindApplication(AppBindData data) { 4855 if (data.trackAllocation) { 4856 DdmVmInternal.enableRecentAllocations(true); 4857 } 4858 4859 mBoundApplication = data; 4860 mConfiguration = new Configuration(data.config); 4861 mCompatConfiguration = new Configuration(data.config); 4862 4863 mProfiler = new Profiler(); 4864 if (data.initProfilerInfo != null) { 4865 mProfiler.profileFile = data.initProfilerInfo.profileFile; 4866 mProfiler.profileFd = data.initProfilerInfo.profileFd; 4867 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; 4868 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; 4869 } 4870 4871 // send up app name; do this *before* waiting for debugger 4872 Process.setArgV0(data.processName); 4873 android.ddm.DdmHandleAppName.setAppName(data.processName, 4874 UserHandle.myUserId()); 4875 4876 if (data.persistent) { 4877 // Persistent processes on low-memory devices do not get to 4878 // use hardware accelerated drawing, since this can add too much 4879 // overhead to the process. 4880 if (!ActivityManager.isHighEndGfx()) { 4881 ThreadedRenderer.disable(false); 4882 } 4883 } 4884 4885 if (mProfiler.profileFd != null) { 4886 mProfiler.startProfiling(); 4887 } 4888 4889 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 4890 // implementation to use the pool executor. Normally, we use the 4891 // serialized executor as the default. This has to happen in the 4892 // main thread so the main looper is set right. 4893 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 4894 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 4895 } 4896 4897 Message.updateCheckRecycle(data.appInfo.targetSdkVersion); 4898 4899 /* 4900 * Before spawning a new process, reset the time zone to be the system time zone. 4901 * This needs to be done because the system time zone could have changed after the 4902 * the spawning of this process. Without doing this this process would have the incorrect 4903 * system time zone. 4904 */ 4905 TimeZone.setDefault(null); 4906 4907 /* 4908 * Initialize the default locales in this process for the reasons we set the time zone. 4909 * 4910 * We do this through ResourcesManager, since we need to do locale negotiation. 4911 */ 4912 mResourcesManager.setDefaultLocalesLocked(data.config.getLocales()); 4913 4914 /* 4915 * Update the system configuration since its preloaded and might not 4916 * reflect configuration changes. The configuration object passed 4917 * in AppBindData can be safely assumed to be up to date 4918 */ 4919 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 4920 mCurDefaultDisplayDpi = data.config.densityDpi; 4921 applyCompatConfiguration(mCurDefaultDisplayDpi); 4922 4923 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4924 4925 /** 4926 * Switch this process to density compatibility mode if needed. 4927 */ 4928 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 4929 == 0) { 4930 mDensityCompatMode = true; 4931 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4932 } 4933 updateDefaultDensity(); 4934 4935 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24)); 4936 DateFormat.set24HourTimePref(is24Hr); 4937 4938 View.mDebugViewAttributes = 4939 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 4940 4941 /** 4942 * For system applications on userdebug/eng builds, log stack 4943 * traces of disk and network access to dropbox for analysis. 4944 */ 4945 if ((data.appInfo.flags & 4946 (ApplicationInfo.FLAG_SYSTEM | 4947 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 4948 StrictMode.conditionallyEnableDebugLogging(); 4949 } 4950 4951 /** 4952 * For apps targetting Honeycomb or later, we don't allow network usage 4953 * on the main event loop / UI thread. This is what ultimately throws 4954 * {@link NetworkOnMainThreadException}. 4955 */ 4956 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) { 4957 StrictMode.enableDeathOnNetwork(); 4958 } 4959 4960 /** 4961 * For apps targetting N or later, we don't allow file:// Uri exposure. 4962 * This is what ultimately throws {@link FileUriExposedException}. 4963 */ 4964 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 4965 StrictMode.enableDeathOnFileUriExposure(); 4966 } 4967 4968 NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted( 4969 (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0); 4970 4971 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 4972 // XXX should have option to change the port. 4973 Debug.changeDebugPort(8100); 4974 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 4975 Slog.w(TAG, "Application " + data.info.getPackageName() 4976 + " is waiting for the debugger on port 8100..."); 4977 4978 IActivityManager mgr = ActivityManagerNative.getDefault(); 4979 try { 4980 mgr.showWaitingForDebugger(mAppThread, true); 4981 } catch (RemoteException ex) { 4982 throw ex.rethrowFromSystemServer(); 4983 } 4984 4985 Debug.waitForDebugger(); 4986 4987 try { 4988 mgr.showWaitingForDebugger(mAppThread, false); 4989 } catch (RemoteException ex) { 4990 throw ex.rethrowFromSystemServer(); 4991 } 4992 4993 } else { 4994 Slog.w(TAG, "Application " + data.info.getPackageName() 4995 + " can be debugged on port 8100..."); 4996 } 4997 } 4998 4999 // Allow application-generated systrace messages if we're debuggable. 5000 boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 5001 Trace.setAppTracingAllowed(isAppDebuggable); 5002 if (isAppDebuggable && data.enableBinderTracking) { 5003 Binder.enableTracing(); 5004 } 5005 5006 /** 5007 * Initialize the default http proxy in this process for the reasons we set the time zone. 5008 */ 5009 final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 5010 if (b != null) { 5011 // In pre-boot mode (doing initial launch to collect password), not 5012 // all system is up. This includes the connectivity service, so don't 5013 // crash if we can't get it. 5014 final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 5015 try { 5016 final ProxyInfo proxyInfo = service.getProxyForNetwork(null); 5017 Proxy.setHttpProxySystemProperty(proxyInfo); 5018 } catch (RemoteException e) { 5019 throw e.rethrowFromSystemServer(); 5020 } 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() && !"android".equals(appContext.getPackageName())) { 5048 // This cache location probably points at credential-encrypted 5049 // storage which may not be accessible yet; assign it anyway instead 5050 // of pointing at device-encrypted storage. 5051 final File cacheDir = appContext.getCacheDir(); 5052 if (cacheDir != null) { 5053 // Provide a usable directory for temporary files 5054 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 5055 } else { 5056 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property " 5057 + "due to missing cache directory"); 5058 } 5059 5060 // Setup a location to store generated/compiled graphics code and 5061 // JIT profiling data. Note that this data is stored in a 5062 // device-encrypted storage area, so these caches must never contain 5063 // user sensitive user data. 5064 final Context deviceContext = appContext.createDeviceEncryptedStorageContext(); 5065 final File codeCacheDir = deviceContext.getCodeCacheDir(); 5066 if (codeCacheDir != null) { 5067 setupGraphicsSupport(data.info, codeCacheDir); 5068 setupJitProfileSupport(data.info, codeCacheDir); 5069 } else { 5070 Log.e(TAG, "Unable to setupGraphicsSupport and setupJitProfileSupport " + 5071 "due to missing code-cache directory"); 5072 } 5073 5074 // Add the lib dir path to hardware renderer so that vulkan layers 5075 // can be searched for within that directory. 5076 ThreadedRenderer.setLibDir(data.info.getLibDir()); 5077 } 5078 5079 // Install the Network Security Config Provider. This must happen before the application 5080 // code is loaded to prevent issues with instances of TLS objects being created before 5081 // the provider is installed. 5082 NetworkSecurityConfigProvider.install(appContext); 5083 5084 // Continue loading instrumentation. 5085 if (ii != null) { 5086 final ApplicationInfo instrApp = new ApplicationInfo(); 5087 ii.copyTo(instrApp); 5088 instrApp.initForUser(UserHandle.myUserId()); 5089 final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 5090 appContext.getClassLoader(), false, true, false); 5091 final ContextImpl instrContext = ContextImpl.createAppContext(this, pi); 5092 5093 try { 5094 final ClassLoader cl = instrContext.getClassLoader(); 5095 mInstrumentation = (Instrumentation) 5096 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 5097 } catch (Exception e) { 5098 throw new RuntimeException( 5099 "Unable to instantiate instrumentation " 5100 + data.instrumentationName + ": " + e.toString(), e); 5101 } 5102 5103 final ComponentName component = new ComponentName(ii.packageName, ii.name); 5104 mInstrumentation.init(this, instrContext, appContext, component, 5105 data.instrumentationWatcher, data.instrumentationUiAutomationConnection); 5106 5107 if (mProfiler.profileFile != null && !ii.handleProfiling 5108 && mProfiler.profileFd == null) { 5109 mProfiler.handlingProfiling = true; 5110 final File file = new File(mProfiler.profileFile); 5111 file.getParentFile().mkdirs(); 5112 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 5113 } 5114 } else { 5115 mInstrumentation = new Instrumentation(); 5116 } 5117 5118 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 5119 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 5120 } else { 5121 // Small heap, clamp to the current growth limit and let the heap release 5122 // pages after the growth limit to the non growth limit capacity. b/18387825 5123 dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); 5124 } 5125 5126 // Allow disk access during application and provider setup. This could 5127 // block processing ordered broadcasts, but later processing would 5128 // probably end up doing the same disk access. 5129 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 5130 try { 5131 // If the app is being launched for full backup or restore, bring it up in 5132 // a restricted environment with the base application class. 5133 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 5134 mInitialApplication = app; 5135 5136 // don't bring up providers in restricted mode; they may depend on the 5137 // app's custom Application class 5138 if (!data.restrictedBackupMode) { 5139 List<ProviderInfo> providers = data.providers; 5140 if (providers != null) { 5141 installContentProviders(app, providers); 5142 // For process that contains content providers, we want to 5143 // ensure that the JIT is enabled "at some point". 5144 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 5145 } 5146 } 5147 5148 // Do this after providers, since instrumentation tests generally start their 5149 // test thread at this point, and we don't want that racing. 5150 try { 5151 mInstrumentation.onCreate(data.instrumentationArgs); 5152 } 5153 catch (Exception e) { 5154 throw new RuntimeException( 5155 "Exception thrown in onCreate() of " 5156 + data.instrumentationName + ": " + e.toString(), e); 5157 } 5158 5159 try { 5160 mInstrumentation.callApplicationOnCreate(app); 5161 } catch (Exception e) { 5162 if (!mInstrumentation.onException(app, e)) { 5163 throw new RuntimeException( 5164 "Unable to create application " + app.getClass().getName() 5165 + ": " + e.toString(), e); 5166 } 5167 } 5168 } finally { 5169 StrictMode.setThreadPolicy(savedPolicy); 5170 } 5171 } 5172 5173 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 5174 IActivityManager am = ActivityManagerNative.getDefault(); 5175 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 5176 && mProfiler.profileFd == null) { 5177 Debug.stopMethodTracing(); 5178 } 5179 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 5180 // + ", app thr: " + mAppThread); 5181 try { 5182 am.finishInstrumentation(mAppThread, resultCode, results); 5183 } catch (RemoteException ex) { 5184 throw ex.rethrowFromSystemServer(); 5185 } 5186 } 5187 5188 private void installContentProviders( 5189 Context context, List<ProviderInfo> providers) { 5190 final ArrayList<IActivityManager.ContentProviderHolder> results = 5191 new ArrayList<IActivityManager.ContentProviderHolder>(); 5192 5193 for (ProviderInfo cpi : providers) { 5194 if (DEBUG_PROVIDER) { 5195 StringBuilder buf = new StringBuilder(128); 5196 buf.append("Pub "); 5197 buf.append(cpi.authority); 5198 buf.append(": "); 5199 buf.append(cpi.name); 5200 Log.i(TAG, buf.toString()); 5201 } 5202 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 5203 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 5204 if (cph != null) { 5205 cph.noReleaseNeeded = true; 5206 results.add(cph); 5207 } 5208 } 5209 5210 try { 5211 ActivityManagerNative.getDefault().publishContentProviders( 5212 getApplicationThread(), results); 5213 } catch (RemoteException ex) { 5214 throw ex.rethrowFromSystemServer(); 5215 } 5216 } 5217 5218 public final IContentProvider acquireProvider( 5219 Context c, String auth, int userId, boolean stable) { 5220 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 5221 if (provider != null) { 5222 return provider; 5223 } 5224 5225 // There is a possible race here. Another thread may try to acquire 5226 // the same provider at the same time. When this happens, we want to ensure 5227 // that the first one wins. 5228 // Note that we cannot hold the lock while acquiring and installing the 5229 // provider since it might take a long time to run and it could also potentially 5230 // be re-entrant in the case where the provider is in the same process. 5231 IActivityManager.ContentProviderHolder holder = null; 5232 try { 5233 holder = ActivityManagerNative.getDefault().getContentProvider( 5234 getApplicationThread(), auth, userId, stable); 5235 } catch (RemoteException ex) { 5236 throw ex.rethrowFromSystemServer(); 5237 } 5238 if (holder == null) { 5239 Slog.e(TAG, "Failed to find provider info for " + auth); 5240 return null; 5241 } 5242 5243 // Install provider will increment the reference count for us, and break 5244 // any ties in the race. 5245 holder = installProvider(c, holder, holder.info, 5246 true /*noisy*/, holder.noReleaseNeeded, stable); 5247 return holder.provider; 5248 } 5249 5250 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 5251 if (stable) { 5252 prc.stableCount += 1; 5253 if (prc.stableCount == 1) { 5254 // We are acquiring a new stable reference on the provider. 5255 int unstableDelta; 5256 if (prc.removePending) { 5257 // We have a pending remove operation, which is holding the 5258 // last unstable reference. At this point we are converting 5259 // that unstable reference to our new stable reference. 5260 unstableDelta = -1; 5261 // Cancel the removal of the provider. 5262 if (DEBUG_PROVIDER) { 5263 Slog.v(TAG, "incProviderRef: stable " 5264 + "snatched provider from the jaws of death"); 5265 } 5266 prc.removePending = false; 5267 // There is a race! It fails to remove the message, which 5268 // will be handled in completeRemoveProvider(). 5269 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5270 } else { 5271 unstableDelta = 0; 5272 } 5273 try { 5274 if (DEBUG_PROVIDER) { 5275 Slog.v(TAG, "incProviderRef Now stable - " 5276 + prc.holder.info.name + ": unstableDelta=" 5277 + unstableDelta); 5278 } 5279 ActivityManagerNative.getDefault().refContentProvider( 5280 prc.holder.connection, 1, unstableDelta); 5281 } catch (RemoteException e) { 5282 //do nothing content provider object is dead any way 5283 } 5284 } 5285 } else { 5286 prc.unstableCount += 1; 5287 if (prc.unstableCount == 1) { 5288 // We are acquiring a new unstable reference on the provider. 5289 if (prc.removePending) { 5290 // Oh look, we actually have a remove pending for the 5291 // provider, which is still holding the last unstable 5292 // reference. We just need to cancel that to take new 5293 // ownership of the reference. 5294 if (DEBUG_PROVIDER) { 5295 Slog.v(TAG, "incProviderRef: unstable " 5296 + "snatched provider from the jaws of death"); 5297 } 5298 prc.removePending = false; 5299 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5300 } else { 5301 // First unstable ref, increment our count in the 5302 // activity manager. 5303 try { 5304 if (DEBUG_PROVIDER) { 5305 Slog.v(TAG, "incProviderRef: Now unstable - " 5306 + prc.holder.info.name); 5307 } 5308 ActivityManagerNative.getDefault().refContentProvider( 5309 prc.holder.connection, 0, 1); 5310 } catch (RemoteException e) { 5311 //do nothing content provider object is dead any way 5312 } 5313 } 5314 } 5315 } 5316 } 5317 5318 public final IContentProvider acquireExistingProvider( 5319 Context c, String auth, int userId, boolean stable) { 5320 synchronized (mProviderMap) { 5321 final ProviderKey key = new ProviderKey(auth, userId); 5322 final ProviderClientRecord pr = mProviderMap.get(key); 5323 if (pr == null) { 5324 return null; 5325 } 5326 5327 IContentProvider provider = pr.mProvider; 5328 IBinder jBinder = provider.asBinder(); 5329 if (!jBinder.isBinderAlive()) { 5330 // The hosting process of the provider has died; we can't 5331 // use this one. 5332 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 5333 + ": existing object's process dead"); 5334 handleUnstableProviderDiedLocked(jBinder, true); 5335 return null; 5336 } 5337 5338 // Only increment the ref count if we have one. If we don't then the 5339 // provider is not reference counted and never needs to be released. 5340 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5341 if (prc != null) { 5342 incProviderRefLocked(prc, stable); 5343 } 5344 return provider; 5345 } 5346 } 5347 5348 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 5349 if (provider == null) { 5350 return false; 5351 } 5352 5353 IBinder jBinder = provider.asBinder(); 5354 synchronized (mProviderMap) { 5355 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5356 if (prc == null) { 5357 // The provider has no ref count, no release is needed. 5358 return false; 5359 } 5360 5361 boolean lastRef = false; 5362 if (stable) { 5363 if (prc.stableCount == 0) { 5364 if (DEBUG_PROVIDER) Slog.v(TAG, 5365 "releaseProvider: stable ref count already 0, how?"); 5366 return false; 5367 } 5368 prc.stableCount -= 1; 5369 if (prc.stableCount == 0) { 5370 // What we do at this point depends on whether there are 5371 // any unstable refs left: if there are, we just tell the 5372 // activity manager to decrement its stable count; if there 5373 // aren't, we need to enqueue this provider to be removed, 5374 // and convert to holding a single unstable ref while 5375 // doing so. 5376 lastRef = prc.unstableCount == 0; 5377 try { 5378 if (DEBUG_PROVIDER) { 5379 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 5380 + lastRef + " - " + prc.holder.info.name); 5381 } 5382 ActivityManagerNative.getDefault().refContentProvider( 5383 prc.holder.connection, -1, lastRef ? 1 : 0); 5384 } catch (RemoteException e) { 5385 //do nothing content provider object is dead any way 5386 } 5387 } 5388 } else { 5389 if (prc.unstableCount == 0) { 5390 if (DEBUG_PROVIDER) Slog.v(TAG, 5391 "releaseProvider: unstable ref count already 0, how?"); 5392 return false; 5393 } 5394 prc.unstableCount -= 1; 5395 if (prc.unstableCount == 0) { 5396 // If this is the last reference, we need to enqueue 5397 // this provider to be removed instead of telling the 5398 // activity manager to remove it at this point. 5399 lastRef = prc.stableCount == 0; 5400 if (!lastRef) { 5401 try { 5402 if (DEBUG_PROVIDER) { 5403 Slog.v(TAG, "releaseProvider: No longer unstable - " 5404 + prc.holder.info.name); 5405 } 5406 ActivityManagerNative.getDefault().refContentProvider( 5407 prc.holder.connection, 0, -1); 5408 } catch (RemoteException e) { 5409 //do nothing content provider object is dead any way 5410 } 5411 } 5412 } 5413 } 5414 5415 if (lastRef) { 5416 if (!prc.removePending) { 5417 // Schedule the actual remove asynchronously, since we don't know the context 5418 // this will be called in. 5419 // TODO: it would be nice to post a delayed message, so 5420 // if we come back and need the same provider quickly 5421 // we will still have it available. 5422 if (DEBUG_PROVIDER) { 5423 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 5424 + prc.holder.info.name); 5425 } 5426 prc.removePending = true; 5427 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 5428 mH.sendMessage(msg); 5429 } else { 5430 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 5431 } 5432 } 5433 return true; 5434 } 5435 } 5436 5437 final void completeRemoveProvider(ProviderRefCount prc) { 5438 synchronized (mProviderMap) { 5439 if (!prc.removePending) { 5440 // There was a race! Some other client managed to acquire 5441 // the provider before the removal was completed. 5442 // Abort the removal. We will do it later. 5443 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 5444 + "provider still in use"); 5445 return; 5446 } 5447 5448 // More complicated race!! Some client managed to acquire the 5449 // provider and release it before the removal was completed. 5450 // Continue the removal, and abort the next remove message. 5451 prc.removePending = false; 5452 5453 final IBinder jBinder = prc.holder.provider.asBinder(); 5454 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 5455 if (existingPrc == prc) { 5456 mProviderRefCountMap.remove(jBinder); 5457 } 5458 5459 for (int i=mProviderMap.size()-1; i>=0; i--) { 5460 ProviderClientRecord pr = mProviderMap.valueAt(i); 5461 IBinder myBinder = pr.mProvider.asBinder(); 5462 if (myBinder == jBinder) { 5463 mProviderMap.removeAt(i); 5464 } 5465 } 5466 } 5467 5468 try { 5469 if (DEBUG_PROVIDER) { 5470 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 5471 + "removeContentProvider(" + prc.holder.info.name + ")"); 5472 } 5473 ActivityManagerNative.getDefault().removeContentProvider( 5474 prc.holder.connection, false); 5475 } catch (RemoteException e) { 5476 //do nothing content provider object is dead any way 5477 } 5478 } 5479 5480 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 5481 synchronized (mProviderMap) { 5482 handleUnstableProviderDiedLocked(provider, fromClient); 5483 } 5484 } 5485 5486 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 5487 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5488 if (prc != null) { 5489 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 5490 + provider + " " + prc.holder.info.name); 5491 mProviderRefCountMap.remove(provider); 5492 for (int i=mProviderMap.size()-1; i>=0; i--) { 5493 ProviderClientRecord pr = mProviderMap.valueAt(i); 5494 if (pr != null && pr.mProvider.asBinder() == provider) { 5495 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 5496 mProviderMap.removeAt(i); 5497 } 5498 } 5499 5500 if (fromClient) { 5501 // We found out about this due to execution in our client 5502 // code. Tell the activity manager about it now, to ensure 5503 // that the next time we go to do anything with the provider 5504 // it knows it is dead (so we don't race with its death 5505 // notification). 5506 try { 5507 ActivityManagerNative.getDefault().unstableProviderDied( 5508 prc.holder.connection); 5509 } catch (RemoteException e) { 5510 //do nothing content provider object is dead any way 5511 } 5512 } 5513 } 5514 } 5515 5516 final void appNotRespondingViaProvider(IBinder provider) { 5517 synchronized (mProviderMap) { 5518 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5519 if (prc != null) { 5520 try { 5521 ActivityManagerNative.getDefault() 5522 .appNotRespondingViaProvider(prc.holder.connection); 5523 } catch (RemoteException e) { 5524 throw e.rethrowFromSystemServer(); 5525 } 5526 } 5527 } 5528 } 5529 5530 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 5531 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 5532 final String auths[] = holder.info.authority.split(";"); 5533 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 5534 5535 final ProviderClientRecord pcr = new ProviderClientRecord( 5536 auths, provider, localProvider, holder); 5537 for (String auth : auths) { 5538 final ProviderKey key = new ProviderKey(auth, userId); 5539 final ProviderClientRecord existing = mProviderMap.get(key); 5540 if (existing != null) { 5541 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 5542 + " already published as " + auth); 5543 } else { 5544 mProviderMap.put(key, pcr); 5545 } 5546 } 5547 return pcr; 5548 } 5549 5550 /** 5551 * Installs the provider. 5552 * 5553 * Providers that are local to the process or that come from the system server 5554 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 5555 * Other remote providers are reference counted. The initial reference count 5556 * for all reference counted providers is one. Providers that are not reference 5557 * counted do not have a reference count (at all). 5558 * 5559 * This method detects when a provider has already been installed. When this happens, 5560 * it increments the reference count of the existing provider (if appropriate) 5561 * and returns the existing provider. This can happen due to concurrent 5562 * attempts to acquire the same provider. 5563 */ 5564 private IActivityManager.ContentProviderHolder installProvider(Context context, 5565 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 5566 boolean noisy, boolean noReleaseNeeded, boolean stable) { 5567 ContentProvider localProvider = null; 5568 IContentProvider provider; 5569 if (holder == null || holder.provider == null) { 5570 if (DEBUG_PROVIDER || noisy) { 5571 Slog.d(TAG, "Loading provider " + info.authority + ": " 5572 + info.name); 5573 } 5574 Context c = null; 5575 ApplicationInfo ai = info.applicationInfo; 5576 if (context.getPackageName().equals(ai.packageName)) { 5577 c = context; 5578 } else if (mInitialApplication != null && 5579 mInitialApplication.getPackageName().equals(ai.packageName)) { 5580 c = mInitialApplication; 5581 } else { 5582 try { 5583 c = context.createPackageContext(ai.packageName, 5584 Context.CONTEXT_INCLUDE_CODE); 5585 } catch (PackageManager.NameNotFoundException e) { 5586 // Ignore 5587 } 5588 } 5589 if (c == null) { 5590 Slog.w(TAG, "Unable to get context for package " + 5591 ai.packageName + 5592 " while loading content provider " + 5593 info.name); 5594 return null; 5595 } 5596 try { 5597 final java.lang.ClassLoader cl = c.getClassLoader(); 5598 localProvider = (ContentProvider)cl. 5599 loadClass(info.name).newInstance(); 5600 provider = localProvider.getIContentProvider(); 5601 if (provider == null) { 5602 Slog.e(TAG, "Failed to instantiate class " + 5603 info.name + " from sourceDir " + 5604 info.applicationInfo.sourceDir); 5605 return null; 5606 } 5607 if (DEBUG_PROVIDER) Slog.v( 5608 TAG, "Instantiating local provider " + info.name); 5609 // XXX Need to create the correct context for this provider. 5610 localProvider.attachInfo(c, info); 5611 } catch (java.lang.Exception e) { 5612 if (!mInstrumentation.onException(null, e)) { 5613 throw new RuntimeException( 5614 "Unable to get provider " + info.name 5615 + ": " + e.toString(), e); 5616 } 5617 return null; 5618 } 5619 } else { 5620 provider = holder.provider; 5621 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 5622 + info.name); 5623 } 5624 5625 IActivityManager.ContentProviderHolder retHolder; 5626 5627 synchronized (mProviderMap) { 5628 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 5629 + " / " + info.name); 5630 IBinder jBinder = provider.asBinder(); 5631 if (localProvider != null) { 5632 ComponentName cname = new ComponentName(info.packageName, info.name); 5633 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 5634 if (pr != null) { 5635 if (DEBUG_PROVIDER) { 5636 Slog.v(TAG, "installProvider: lost the race, " 5637 + "using existing local provider"); 5638 } 5639 provider = pr.mProvider; 5640 } else { 5641 holder = new IActivityManager.ContentProviderHolder(info); 5642 holder.provider = provider; 5643 holder.noReleaseNeeded = true; 5644 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 5645 mLocalProviders.put(jBinder, pr); 5646 mLocalProvidersByName.put(cname, pr); 5647 } 5648 retHolder = pr.mHolder; 5649 } else { 5650 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5651 if (prc != null) { 5652 if (DEBUG_PROVIDER) { 5653 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 5654 } 5655 // We need to transfer our new reference to the existing 5656 // ref count, releasing the old one... but only if 5657 // release is needed (that is, it is not running in the 5658 // system process). 5659 if (!noReleaseNeeded) { 5660 incProviderRefLocked(prc, stable); 5661 try { 5662 ActivityManagerNative.getDefault().removeContentProvider( 5663 holder.connection, stable); 5664 } catch (RemoteException e) { 5665 //do nothing content provider object is dead any way 5666 } 5667 } 5668 } else { 5669 ProviderClientRecord client = installProviderAuthoritiesLocked( 5670 provider, localProvider, holder); 5671 if (noReleaseNeeded) { 5672 prc = new ProviderRefCount(holder, client, 1000, 1000); 5673 } else { 5674 prc = stable 5675 ? new ProviderRefCount(holder, client, 1, 0) 5676 : new ProviderRefCount(holder, client, 0, 1); 5677 } 5678 mProviderRefCountMap.put(jBinder, prc); 5679 } 5680 retHolder = prc.holder; 5681 } 5682 } 5683 5684 return retHolder; 5685 } 5686 5687 private void attach(boolean system) { 5688 sCurrentActivityThread = this; 5689 mSystemThread = system; 5690 if (!system) { 5691 ViewRootImpl.addFirstDrawHandler(new Runnable() { 5692 @Override 5693 public void run() { 5694 ensureJitEnabled(); 5695 } 5696 }); 5697 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 5698 UserHandle.myUserId()); 5699 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 5700 final IActivityManager mgr = ActivityManagerNative.getDefault(); 5701 try { 5702 mgr.attachApplication(mAppThread); 5703 } catch (RemoteException ex) { 5704 throw ex.rethrowFromSystemServer(); 5705 } 5706 // Watch for getting close to heap limit. 5707 BinderInternal.addGcWatcher(new Runnable() { 5708 @Override public void run() { 5709 if (!mSomeActivitiesChanged) { 5710 return; 5711 } 5712 Runtime runtime = Runtime.getRuntime(); 5713 long dalvikMax = runtime.maxMemory(); 5714 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); 5715 if (dalvikUsed > ((3*dalvikMax)/4)) { 5716 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) 5717 + " total=" + (runtime.totalMemory()/1024) 5718 + " used=" + (dalvikUsed/1024)); 5719 mSomeActivitiesChanged = false; 5720 try { 5721 mgr.releaseSomeActivities(mAppThread); 5722 } catch (RemoteException e) { 5723 throw e.rethrowFromSystemServer(); 5724 } 5725 } 5726 } 5727 }); 5728 } else { 5729 // Don't set application object here -- if the system crashes, 5730 // we can't display an alert, we just want to die die die. 5731 android.ddm.DdmHandleAppName.setAppName("system_process", 5732 UserHandle.myUserId()); 5733 try { 5734 mInstrumentation = new Instrumentation(); 5735 ContextImpl context = ContextImpl.createAppContext( 5736 this, getSystemContext().mPackageInfo); 5737 mInitialApplication = context.mPackageInfo.makeApplication(true, null); 5738 mInitialApplication.onCreate(); 5739 } catch (Exception e) { 5740 throw new RuntimeException( 5741 "Unable to instantiate Application():" + e.toString(), e); 5742 } 5743 } 5744 5745 // add dropbox logging to libcore 5746 DropBox.setReporter(new DropBoxReporter()); 5747 5748 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 5749 @Override 5750 public void onConfigurationChanged(Configuration newConfig) { 5751 synchronized (mResourcesManager) { 5752 // We need to apply this change to the resources 5753 // immediately, because upon returning the view 5754 // hierarchy will be informed about it. 5755 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { 5756 // This actually changed the resources! Tell 5757 // everyone about it. 5758 if (mPendingConfiguration == null || 5759 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 5760 mPendingConfiguration = newConfig; 5761 5762 sendMessage(H.CONFIGURATION_CHANGED, newConfig); 5763 } 5764 } 5765 } 5766 } 5767 @Override 5768 public void onLowMemory() { 5769 } 5770 @Override 5771 public void onTrimMemory(int level) { 5772 } 5773 }); 5774 } 5775 5776 public static ActivityThread systemMain() { 5777 // The system process on low-memory devices do not get to use hardware 5778 // accelerated drawing, since this can add too much overhead to the 5779 // process. 5780 if (!ActivityManager.isHighEndGfx()) { 5781 ThreadedRenderer.disable(true); 5782 } else { 5783 ThreadedRenderer.enableForegroundTrimming(); 5784 } 5785 ActivityThread thread = new ActivityThread(); 5786 thread.attach(true); 5787 return thread; 5788 } 5789 5790 public final void installSystemProviders(List<ProviderInfo> providers) { 5791 if (providers != null) { 5792 installContentProviders(mInitialApplication, providers); 5793 } 5794 } 5795 5796 public int getIntCoreSetting(String key, int defaultValue) { 5797 synchronized (mResourcesManager) { 5798 if (mCoreSettings != null) { 5799 return mCoreSettings.getInt(key, defaultValue); 5800 } 5801 return defaultValue; 5802 } 5803 } 5804 5805 private static class EventLoggingReporter implements EventLogger.Reporter { 5806 @Override 5807 public void report (int code, Object... list) { 5808 EventLog.writeEvent(code, list); 5809 } 5810 } 5811 5812 private class DropBoxReporter implements DropBox.Reporter { 5813 5814 private DropBoxManager dropBox; 5815 5816 public DropBoxReporter() {} 5817 5818 @Override 5819 public void addData(String tag, byte[] data, int flags) { 5820 ensureInitialized(); 5821 dropBox.addData(tag, data, flags); 5822 } 5823 5824 @Override 5825 public void addText(String tag, String data) { 5826 ensureInitialized(); 5827 dropBox.addText(tag, data); 5828 } 5829 5830 private synchronized void ensureInitialized() { 5831 if (dropBox == null) { 5832 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 5833 } 5834 } 5835 } 5836 5837 public static void main(String[] args) { 5838 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); 5839 SamplingProfilerIntegration.start(); 5840 5841 // CloseGuard defaults to true and can be quite spammy. We 5842 // disable it here, but selectively enable it later (via 5843 // StrictMode) on debug builds, but using DropBox, not logs. 5844 CloseGuard.setEnabled(false); 5845 5846 Environment.initForCurrentUser(); 5847 5848 // Set the reporter for event logging in libcore 5849 EventLogger.setReporter(new EventLoggingReporter()); 5850 5851 AndroidKeyStoreProvider.install(); 5852 5853 // Make sure TrustedCertificateStore looks in the right place for CA certificates 5854 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); 5855 TrustedCertificateStore.setDefaultUserDirectory(configDir); 5856 5857 Process.setArgV0("<pre-initialized>"); 5858 5859 Looper.prepareMainLooper(); 5860 5861 ActivityThread thread = new ActivityThread(); 5862 thread.attach(false); 5863 5864 if (sMainThreadHandler == null) { 5865 sMainThreadHandler = thread.getHandler(); 5866 } 5867 5868 if (false) { 5869 Looper.myLooper().setMessageLogging(new 5870 LogPrinter(Log.DEBUG, "ActivityThread")); 5871 } 5872 5873 // End of event ActivityThreadMain. 5874 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5875 Looper.loop(); 5876 5877 throw new RuntimeException("Main thread loop unexpectedly exited"); 5878 } 5879} 5880