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