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