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