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