ActivityThread.java revision 75f5de62fe4f7b529e51c6f3181483ed574cbd58
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.app; 18 19import android.app.assist.AssistContent; 20import android.app.assist.AssistStructure; 21import android.app.backup.BackupAgent; 22import android.content.BroadcastReceiver; 23import android.content.ComponentCallbacks2; 24import android.content.ComponentName; 25import android.content.ContentProvider; 26import android.content.Context; 27import android.content.IContentProvider; 28import android.content.Intent; 29import android.content.IIntentReceiver; 30import android.content.pm.ActivityInfo; 31import android.content.pm.ApplicationInfo; 32import android.content.pm.IPackageManager; 33import android.content.pm.InstrumentationInfo; 34import android.content.pm.PackageInfo; 35import android.content.pm.PackageManager; 36import android.content.pm.PackageManager.NameNotFoundException; 37import android.content.pm.ProviderInfo; 38import android.content.pm.ServiceInfo; 39import android.content.res.AssetManager; 40import android.content.res.CompatibilityInfo; 41import android.content.res.Configuration; 42import android.content.res.Resources; 43import android.content.res.Resources.Theme; 44import android.database.sqlite.SQLiteDatabase; 45import android.database.sqlite.SQLiteDebug; 46import android.database.sqlite.SQLiteDebug.DbStats; 47import android.graphics.Bitmap; 48import android.graphics.Canvas; 49import android.hardware.display.DisplayManagerGlobal; 50import android.net.ConnectivityManager; 51import android.net.IConnectivityManager; 52import android.net.Network; 53import android.net.Proxy; 54import android.net.ProxyInfo; 55import android.net.Uri; 56import android.os.AsyncTask; 57import android.os.Binder; 58import android.os.Build; 59import android.os.Bundle; 60import android.os.Debug; 61import android.os.DropBoxManager; 62import android.os.Environment; 63import android.os.Handler; 64import android.os.IBinder; 65import android.os.Looper; 66import android.os.Message; 67import android.os.MessageQueue; 68import android.os.Parcel; 69import android.os.ParcelFileDescriptor; 70import android.os.PersistableBundle; 71import android.os.Process; 72import android.os.RemoteException; 73import android.os.ServiceManager; 74import android.os.StrictMode; 75import android.os.SystemClock; 76import android.os.SystemProperties; 77import android.os.Trace; 78import android.os.TransactionTooLargeException; 79import android.os.UserHandle; 80import android.provider.Settings; 81import android.security.NetworkSecurityPolicy; 82import android.security.net.config.NetworkSecurityConfigProvider; 83import android.util.AndroidRuntimeException; 84import android.util.ArrayMap; 85import android.util.DisplayMetrics; 86import android.util.EventLog; 87import android.util.Log; 88import android.util.LogPrinter; 89import android.util.Pair; 90import android.util.PrintWriterPrinter; 91import android.util.Slog; 92import android.util.SparseIntArray; 93import android.util.SuperNotCalledException; 94import android.view.Display; 95import android.view.ThreadedRenderer; 96import android.view.View; 97import android.view.ViewDebug; 98import android.view.ViewManager; 99import android.view.ViewRootImpl; 100import android.view.Window; 101import android.view.WindowManager; 102import android.view.WindowManagerGlobal; 103import android.renderscript.RenderScriptCacheDir; 104import android.security.keystore.AndroidKeyStoreProvider; 105import android.system.Os; 106import android.system.OsConstants; 107import android.system.ErrnoException; 108 109import com.android.internal.annotations.GuardedBy; 110import com.android.internal.app.IVoiceInteractor; 111import com.android.internal.content.ReferrerIntent; 112import com.android.internal.os.BinderInternal; 113import com.android.internal.os.RuntimeInit; 114import com.android.internal.os.SamplingProfilerIntegration; 115import com.android.internal.os.SomeArgs; 116import com.android.internal.util.FastPrintWriter; 117import com.android.org.conscrypt.OpenSSLSocketImpl; 118import com.android.org.conscrypt.TrustedCertificateStore; 119import com.google.android.collect.Lists; 120 121import java.io.File; 122import java.io.FileDescriptor; 123import java.io.FileOutputStream; 124import java.io.IOException; 125import java.io.PrintWriter; 126import java.lang.ref.WeakReference; 127import java.net.InetAddress; 128import java.text.DateFormat; 129import java.util.ArrayList; 130import java.util.Collections; 131import java.util.List; 132import java.util.Map; 133import java.util.Objects; 134import java.util.TimeZone; 135 136import libcore.io.DropBox; 137import libcore.io.EventLogger; 138import libcore.io.IoUtils; 139import libcore.net.event.NetworkEventDispatcher; 140import dalvik.system.CloseGuard; 141import dalvik.system.VMDebug; 142import dalvik.system.VMRuntime; 143import org.apache.harmony.dalvik.ddmc.DdmVmInternal; 144 145final class RemoteServiceException extends AndroidRuntimeException { 146 public RemoteServiceException(String msg) { 147 super(msg); 148 } 149} 150 151/** 152 * This manages the execution of the main thread in an 153 * application process, scheduling and executing activities, 154 * broadcasts, and other operations on it as the activity 155 * manager requests. 156 * 157 * {@hide} 158 */ 159public final class ActivityThread { 160 /** @hide */ 161 public static final String TAG = "ActivityThread"; 162 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565; 163 static final boolean localLOGV = false; 164 static final boolean DEBUG_MESSAGES = false; 165 /** @hide */ 166 public static final boolean DEBUG_BROADCAST = false; 167 private static final boolean DEBUG_RESULTS = false; 168 private static final boolean DEBUG_BACKUP = false; 169 public static final boolean DEBUG_CONFIGURATION = false; 170 private static final boolean DEBUG_SERVICE = false; 171 private static final boolean DEBUG_MEMORY_TRIM = false; 172 private static final boolean DEBUG_PROVIDER = false; 173 private static final boolean DEBUG_ORDER = false; 174 private static final long MIN_TIME_BETWEEN_GCS = 5*1000; 175 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; 176 private static final int LOG_AM_ON_PAUSE_CALLED = 30021; 177 private static final int LOG_AM_ON_RESUME_CALLED = 30022; 178 private static final int LOG_AM_ON_STOP_CALLED = 30049; 179 180 /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */ 181 public static final int SERVICE_DONE_EXECUTING_ANON = 0; 182 /** Type for IActivityManager.serviceDoneExecuting: done with an onStart call */ 183 public static final int SERVICE_DONE_EXECUTING_START = 1; 184 /** Type for IActivityManager.serviceDoneExecuting: done stopping (destroying) service */ 185 public static final int SERVICE_DONE_EXECUTING_STOP = 2; 186 187 // Details for pausing activity. 188 private static final int USER_LEAVING = 1; 189 private static final int DONT_REPORT = 2; 190 191 // Whether to invoke an activity callback after delivering new configuration. 192 private static final boolean REPORT_TO_ACTIVITY = true; 193 194 private ContextImpl mSystemContext; 195 196 static IPackageManager sPackageManager; 197 198 final ApplicationThread mAppThread = new ApplicationThread(); 199 final Looper mLooper = Looper.myLooper(); 200 final H mH = new H(); 201 final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>(); 202 // List of new activities (via ActivityRecord.nextIdle) that should 203 // be reported when next we idle. 204 ActivityClientRecord mNewActivities = null; 205 // Number of activities that are currently visible on-screen. 206 int mNumVisibleActivities = 0; 207 WeakReference<AssistStructure> mLastAssistStructure; 208 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); 209 AppBindData mBoundApplication; 210 Profiler mProfiler; 211 int mCurDefaultDisplayDpi; 212 boolean mDensityCompatMode; 213 Configuration mConfiguration; 214 Configuration mCompatConfiguration; 215 Application mInitialApplication; 216 final ArrayList<Application> mAllApplications 217 = new ArrayList<Application>(); 218 // set of instantiated backup agents, keyed by package name 219 final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>(); 220 /** Reference to singleton {@link ActivityThread} */ 221 private static ActivityThread sCurrentActivityThread; 222 Instrumentation mInstrumentation; 223 String mInstrumentationPackageName = null; 224 String mInstrumentationAppDir = null; 225 String[] mInstrumentationSplitAppDirs = null; 226 String mInstrumentationLibDir = null; 227 String mInstrumentedAppDir = null; 228 String[] mInstrumentedSplitAppDirs = null; 229 String mInstrumentedLibDir = null; 230 boolean mSystemThread = false; 231 boolean mJitEnabled = false; 232 boolean mSomeActivitiesChanged = false; 233 234 // These can be accessed by multiple threads; mPackages is the lock. 235 // XXX For now we keep around information about all packages we have 236 // seen, not removing entries from this map. 237 // NOTE: The activity and window managers need to call in to 238 // ActivityThread to do things like update resource configurations, 239 // which means this lock gets held while the activity and window managers 240 // holds their own lock. Thus you MUST NEVER call back into the activity manager 241 // or window manager or anything that depends on them while holding this lock. 242 // These LoadedApk are only valid for the userId that we're running as. 243 final ArrayMap<String, WeakReference<LoadedApk>> mPackages 244 = new ArrayMap<String, WeakReference<LoadedApk>>(); 245 final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages 246 = new ArrayMap<String, WeakReference<LoadedApk>>(); 247 final ArrayList<ActivityClientRecord> mRelaunchingActivities 248 = new ArrayList<ActivityClientRecord>(); 249 Configuration mPendingConfiguration = null; 250 // Because we merge activity relaunch operations we can't depend on the ordering provided by 251 // the handler messages. We need to introduce secondary ordering mechanism, which will allow 252 // us to drop certain events, if we know that they happened before relaunch we already executed. 253 // This represents the order of receiving the request from AM. 254 @GuardedBy("mResourcesManager") 255 int mLifecycleSeq = 0; 256 257 private final ResourcesManager mResourcesManager; 258 259 private static final class ProviderKey { 260 final String authority; 261 final int userId; 262 263 public ProviderKey(String authority, int userId) { 264 this.authority = authority; 265 this.userId = userId; 266 } 267 268 @Override 269 public boolean equals(Object o) { 270 if (o instanceof ProviderKey) { 271 final ProviderKey other = (ProviderKey) o; 272 return Objects.equals(authority, other.authority) && userId == other.userId; 273 } 274 return false; 275 } 276 277 @Override 278 public int hashCode() { 279 return ((authority != null) ? authority.hashCode() : 0) ^ userId; 280 } 281 } 282 283 // The lock of mProviderMap protects the following variables. 284 final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap 285 = new ArrayMap<ProviderKey, ProviderClientRecord>(); 286 final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap 287 = new ArrayMap<IBinder, ProviderRefCount>(); 288 final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders 289 = new ArrayMap<IBinder, ProviderClientRecord>(); 290 final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName 291 = new ArrayMap<ComponentName, ProviderClientRecord>(); 292 293 final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners 294 = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); 295 296 final GcIdler mGcIdler = new GcIdler(); 297 boolean mGcIdlerScheduled = false; 298 299 static Handler sMainThreadHandler; // set once in main() 300 301 Bundle mCoreSettings = null; 302 303 static final class ActivityClientRecord { 304 IBinder token; 305 int ident; 306 Intent intent; 307 String referrer; 308 IVoiceInteractor voiceInteractor; 309 Bundle state; 310 PersistableBundle persistentState; 311 Activity activity; 312 Window window; 313 Activity parent; 314 String embeddedID; 315 Activity.NonConfigurationInstances lastNonConfigurationInstances; 316 boolean paused; 317 boolean stopped; 318 boolean hideForNow; 319 Configuration newConfig; 320 Configuration createdConfig; 321 Configuration overrideConfig; 322 // Used for consolidating configs before sending on to Activity. 323 private Configuration tmpConfig = new Configuration(); 324 ActivityClientRecord nextIdle; 325 326 ProfilerInfo profilerInfo; 327 328 ActivityInfo activityInfo; 329 CompatibilityInfo compatInfo; 330 LoadedApk packageInfo; 331 332 List<ResultInfo> pendingResults; 333 List<ReferrerIntent> pendingIntents; 334 335 boolean startsNotResumed; 336 boolean isForward; 337 int pendingConfigChanges; 338 boolean onlyLocalRequest; 339 340 Window mPendingRemoveWindow; 341 WindowManager mPendingRemoveWindowManager; 342 boolean mPreserveWindow; 343 344 // Set for relaunch requests, indicates the order number of the relaunch operation, so it 345 // can be compared with other lifecycle operations. 346 int relaunchSeq = 0; 347 348 // Can only be accessed from the UI thread. This represents the latest processed message 349 // that is related to lifecycle events/ 350 int lastProcessedSeq = 0; 351 352 ActivityClientRecord() { 353 parent = null; 354 embeddedID = null; 355 paused = false; 356 stopped = false; 357 hideForNow = false; 358 nextIdle = null; 359 } 360 361 public boolean isPreHoneycomb() { 362 if (activity != null) { 363 return activity.getApplicationInfo().targetSdkVersion 364 < android.os.Build.VERSION_CODES.HONEYCOMB; 365 } 366 return false; 367 } 368 369 public boolean isPersistable() { 370 return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS; 371 } 372 373 public String toString() { 374 ComponentName componentName = intent != null ? intent.getComponent() : null; 375 return "ActivityRecord{" 376 + Integer.toHexString(System.identityHashCode(this)) 377 + " token=" + token + " " + (componentName == null 378 ? "no component name" : componentName.toShortString()) 379 + "}"; 380 } 381 } 382 383 final class ProviderClientRecord { 384 final String[] mNames; 385 final IContentProvider mProvider; 386 final ContentProvider mLocalProvider; 387 final IActivityManager.ContentProviderHolder mHolder; 388 389 ProviderClientRecord(String[] names, IContentProvider provider, 390 ContentProvider localProvider, 391 IActivityManager.ContentProviderHolder holder) { 392 mNames = names; 393 mProvider = provider; 394 mLocalProvider = localProvider; 395 mHolder = holder; 396 } 397 } 398 399 static final class NewIntentData { 400 List<ReferrerIntent> intents; 401 IBinder token; 402 public String toString() { 403 return "NewIntentData{intents=" + intents + " token=" + token + "}"; 404 } 405 } 406 407 static final class ReceiverData extends BroadcastReceiver.PendingResult { 408 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras, 409 boolean ordered, boolean sticky, IBinder token, int sendingUser) { 410 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky, 411 token, sendingUser, intent.getFlags()); 412 this.intent = intent; 413 } 414 415 Intent intent; 416 ActivityInfo info; 417 CompatibilityInfo compatInfo; 418 public String toString() { 419 return "ReceiverData{intent=" + intent + " packageName=" + 420 info.packageName + " resultCode=" + getResultCode() 421 + " resultData=" + getResultData() + " resultExtras=" 422 + getResultExtras(false) + "}"; 423 } 424 } 425 426 static final class CreateBackupAgentData { 427 ApplicationInfo appInfo; 428 CompatibilityInfo compatInfo; 429 int backupMode; 430 public String toString() { 431 return "CreateBackupAgentData{appInfo=" + appInfo 432 + " backupAgent=" + appInfo.backupAgentName 433 + " mode=" + backupMode + "}"; 434 } 435 } 436 437 static final class CreateServiceData { 438 IBinder token; 439 ServiceInfo info; 440 CompatibilityInfo compatInfo; 441 Intent intent; 442 public String toString() { 443 return "CreateServiceData{token=" + token + " className=" 444 + info.name + " packageName=" + info.packageName 445 + " intent=" + intent + "}"; 446 } 447 } 448 449 static final class BindServiceData { 450 IBinder token; 451 Intent intent; 452 boolean rebind; 453 public String toString() { 454 return "BindServiceData{token=" + token + " intent=" + intent + "}"; 455 } 456 } 457 458 static final class ServiceArgsData { 459 IBinder token; 460 boolean taskRemoved; 461 int startId; 462 int flags; 463 Intent args; 464 public String toString() { 465 return "ServiceArgsData{token=" + token + " startId=" + startId 466 + " args=" + args + "}"; 467 } 468 } 469 470 static final class AppBindData { 471 LoadedApk info; 472 String processName; 473 ApplicationInfo appInfo; 474 List<ProviderInfo> providers; 475 ComponentName instrumentationName; 476 Bundle instrumentationArgs; 477 IInstrumentationWatcher instrumentationWatcher; 478 IUiAutomationConnection instrumentationUiAutomationConnection; 479 int debugMode; 480 boolean enableBinderTracking; 481 boolean trackAllocation; 482 boolean restrictedBackupMode; 483 boolean persistent; 484 Configuration config; 485 CompatibilityInfo compatInfo; 486 487 /** Initial values for {@link Profiler}. */ 488 ProfilerInfo initProfilerInfo; 489 490 public String toString() { 491 return "AppBindData{appInfo=" + appInfo + "}"; 492 } 493 } 494 495 static final class Profiler { 496 String profileFile; 497 ParcelFileDescriptor profileFd; 498 int samplingInterval; 499 boolean autoStopProfiler; 500 boolean profiling; 501 boolean handlingProfiling; 502 public void setProfiler(ProfilerInfo profilerInfo) { 503 ParcelFileDescriptor fd = profilerInfo.profileFd; 504 if (profiling) { 505 if (fd != null) { 506 try { 507 fd.close(); 508 } catch (IOException e) { 509 // Ignore 510 } 511 } 512 return; 513 } 514 if (profileFd != null) { 515 try { 516 profileFd.close(); 517 } catch (IOException e) { 518 // Ignore 519 } 520 } 521 profileFile = profilerInfo.profileFile; 522 profileFd = fd; 523 samplingInterval = profilerInfo.samplingInterval; 524 autoStopProfiler = profilerInfo.autoStopProfiler; 525 } 526 public void startProfiling() { 527 if (profileFd == null || profiling) { 528 return; 529 } 530 try { 531 VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(), 532 8 * 1024 * 1024, 0, samplingInterval != 0, samplingInterval); 533 profiling = true; 534 } catch (RuntimeException e) { 535 Slog.w(TAG, "Profiling failed on path " + profileFile); 536 try { 537 profileFd.close(); 538 profileFd = null; 539 } catch (IOException e2) { 540 Slog.w(TAG, "Failure closing profile fd", e2); 541 } 542 } 543 } 544 public void stopProfiling() { 545 if (profiling) { 546 profiling = false; 547 Debug.stopMethodTracing(); 548 if (profileFd != null) { 549 try { 550 profileFd.close(); 551 } catch (IOException e) { 552 } 553 } 554 profileFd = null; 555 profileFile = null; 556 } 557 } 558 } 559 560 static final class DumpComponentInfo { 561 ParcelFileDescriptor fd; 562 IBinder token; 563 String prefix; 564 String[] args; 565 } 566 567 static final class ResultData { 568 IBinder token; 569 List<ResultInfo> results; 570 public String toString() { 571 return "ResultData{token=" + token + " results" + results + "}"; 572 } 573 } 574 575 static final class ContextCleanupInfo { 576 ContextImpl context; 577 String what; 578 String who; 579 } 580 581 static final class DumpHeapData { 582 String path; 583 ParcelFileDescriptor fd; 584 } 585 586 static final class UpdateCompatibilityData { 587 String pkg; 588 CompatibilityInfo info; 589 } 590 591 static final class RequestAssistContextExtras { 592 IBinder activityToken; 593 IBinder requestToken; 594 int requestType; 595 } 596 597 static final class ActivityConfigChangeData { 598 final IBinder activityToken; 599 final Configuration overrideConfig; 600 public ActivityConfigChangeData(IBinder token, Configuration config) { 601 activityToken = token; 602 overrideConfig = config; 603 } 604 } 605 606 private native void dumpGraphicsInfo(FileDescriptor fd); 607 608 private class ApplicationThread extends ApplicationThreadNative { 609 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; 610 611 private int mLastProcessState = -1; 612 613 private void updatePendingConfiguration(Configuration config) { 614 synchronized (mResourcesManager) { 615 if (mPendingConfiguration == null || 616 mPendingConfiguration.isOtherSeqNewer(config)) { 617 mPendingConfiguration = config; 618 } 619 } 620 } 621 622 public final void schedulePauseActivity(IBinder token, boolean finished, 623 boolean userLeaving, int configChanges, boolean dontReport) { 624 int seq = getLifecycleSeq(); 625 if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this 626 + " operation received seq: " + seq); 627 sendMessage( 628 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, 629 token, 630 (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0), 631 configChanges, 632 seq); 633 } 634 635 public final void scheduleStopActivity(IBinder token, boolean showWindow, 636 int configChanges) { 637 int seq = getLifecycleSeq(); 638 if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this 639 + " operation received seq: " + seq); 640 sendMessage( 641 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, 642 token, 0, configChanges, seq); 643 } 644 645 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) { 646 sendMessage( 647 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW, 648 token); 649 } 650 651 public final void scheduleSleeping(IBinder token, boolean sleeping) { 652 sendMessage(H.SLEEPING, token, sleeping ? 1 : 0); 653 } 654 655 public final void scheduleResumeActivity(IBinder token, int processState, 656 boolean isForward, Bundle resumeArgs) { 657 int seq = getLifecycleSeq(); 658 if (DEBUG_ORDER) Slog.d(TAG, "resumeActivity " + ActivityThread.this 659 + " operation received seq: " + seq); 660 updateProcessState(processState, false); 661 sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq); 662 } 663 664 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) { 665 ResultData res = new ResultData(); 666 res.token = token; 667 res.results = results; 668 sendMessage(H.SEND_RESULT, res); 669 } 670 671 // we use token to identify this activity without having to send the 672 // activity itself back to the activity manager. (matters more with ipc) 673 @Override 674 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, 675 ActivityInfo info, Configuration curConfig, Configuration overrideConfig, 676 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, 677 int procState, Bundle state, PersistableBundle persistentState, 678 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 679 boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { 680 681 updateProcessState(procState, false); 682 683 ActivityClientRecord r = new ActivityClientRecord(); 684 685 r.token = token; 686 r.ident = ident; 687 r.intent = intent; 688 r.referrer = referrer; 689 r.voiceInteractor = voiceInteractor; 690 r.activityInfo = info; 691 r.compatInfo = compatInfo; 692 r.state = state; 693 r.persistentState = persistentState; 694 695 r.pendingResults = pendingResults; 696 r.pendingIntents = pendingNewIntents; 697 698 r.startsNotResumed = notResumed; 699 r.isForward = isForward; 700 701 r.profilerInfo = profilerInfo; 702 703 r.overrideConfig = overrideConfig; 704 updatePendingConfiguration(curConfig); 705 706 sendMessage(H.LAUNCH_ACTIVITY, r); 707 } 708 709 @Override 710 public final void scheduleRelaunchActivity(IBinder token, 711 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 712 int configChanges, boolean notResumed, Configuration config, 713 Configuration overrideConfig, boolean preserveWindow) { 714 requestRelaunchActivity(token, pendingResults, pendingNewIntents, 715 configChanges, notResumed, config, overrideConfig, true, preserveWindow); 716 } 717 718 public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) { 719 NewIntentData data = new NewIntentData(); 720 data.intents = intents; 721 data.token = token; 722 723 sendMessage(H.NEW_INTENT, data); 724 } 725 726 public final void scheduleDestroyActivity(IBinder token, boolean finishing, 727 int configChanges) { 728 sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0, 729 configChanges); 730 } 731 732 public final void scheduleReceiver(Intent intent, ActivityInfo info, 733 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, 734 boolean sync, int sendingUser, int processState) { 735 updateProcessState(processState, false); 736 ReceiverData r = new ReceiverData(intent, resultCode, data, extras, 737 sync, false, mAppThread.asBinder(), sendingUser); 738 r.info = info; 739 r.compatInfo = compatInfo; 740 sendMessage(H.RECEIVER, r); 741 } 742 743 public final void scheduleCreateBackupAgent(ApplicationInfo app, 744 CompatibilityInfo compatInfo, int backupMode) { 745 CreateBackupAgentData d = new CreateBackupAgentData(); 746 d.appInfo = app; 747 d.compatInfo = compatInfo; 748 d.backupMode = backupMode; 749 750 sendMessage(H.CREATE_BACKUP_AGENT, d); 751 } 752 753 public final void scheduleDestroyBackupAgent(ApplicationInfo app, 754 CompatibilityInfo compatInfo) { 755 CreateBackupAgentData d = new CreateBackupAgentData(); 756 d.appInfo = app; 757 d.compatInfo = compatInfo; 758 759 sendMessage(H.DESTROY_BACKUP_AGENT, d); 760 } 761 762 public final void scheduleCreateService(IBinder token, 763 ServiceInfo info, CompatibilityInfo compatInfo, int processState) { 764 updateProcessState(processState, false); 765 CreateServiceData s = new CreateServiceData(); 766 s.token = token; 767 s.info = info; 768 s.compatInfo = compatInfo; 769 770 sendMessage(H.CREATE_SERVICE, s); 771 } 772 773 public final void scheduleBindService(IBinder token, Intent intent, 774 boolean rebind, int processState) { 775 updateProcessState(processState, false); 776 BindServiceData s = new BindServiceData(); 777 s.token = token; 778 s.intent = intent; 779 s.rebind = rebind; 780 781 if (DEBUG_SERVICE) 782 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" 783 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); 784 sendMessage(H.BIND_SERVICE, s); 785 } 786 787 public final void scheduleUnbindService(IBinder token, Intent intent) { 788 BindServiceData s = new BindServiceData(); 789 s.token = token; 790 s.intent = intent; 791 792 sendMessage(H.UNBIND_SERVICE, s); 793 } 794 795 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId, 796 int flags ,Intent args) { 797 ServiceArgsData s = new ServiceArgsData(); 798 s.token = token; 799 s.taskRemoved = taskRemoved; 800 s.startId = startId; 801 s.flags = flags; 802 s.args = args; 803 804 sendMessage(H.SERVICE_ARGS, s); 805 } 806 807 public final void scheduleStopService(IBinder token) { 808 sendMessage(H.STOP_SERVICE, token); 809 } 810 811 public final void bindApplication(String processName, ApplicationInfo appInfo, 812 List<ProviderInfo> providers, ComponentName instrumentationName, 813 ProfilerInfo profilerInfo, Bundle instrumentationArgs, 814 IInstrumentationWatcher instrumentationWatcher, 815 IUiAutomationConnection instrumentationUiConnection, int debugMode, 816 boolean enableBinderTracking, boolean trackAllocation, 817 boolean isRestrictedBackupMode, boolean persistent, Configuration config, 818 CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) { 819 820 if (services != null) { 821 // Setup the service cache in the ServiceManager 822 ServiceManager.initServiceCache(services); 823 } 824 825 setCoreSettings(coreSettings); 826 827 AppBindData data = new AppBindData(); 828 data.processName = processName; 829 data.appInfo = appInfo; 830 data.providers = providers; 831 data.instrumentationName = instrumentationName; 832 data.instrumentationArgs = instrumentationArgs; 833 data.instrumentationWatcher = instrumentationWatcher; 834 data.instrumentationUiAutomationConnection = instrumentationUiConnection; 835 data.debugMode = debugMode; 836 data.enableBinderTracking = enableBinderTracking; 837 data.trackAllocation = trackAllocation; 838 data.restrictedBackupMode = isRestrictedBackupMode; 839 data.persistent = persistent; 840 data.config = config; 841 data.compatInfo = compatInfo; 842 data.initProfilerInfo = profilerInfo; 843 sendMessage(H.BIND_APPLICATION, data); 844 } 845 846 public final void scheduleExit() { 847 sendMessage(H.EXIT_APPLICATION, null); 848 } 849 850 public final void scheduleSuicide() { 851 sendMessage(H.SUICIDE, null); 852 } 853 854 public void scheduleConfigurationChanged(Configuration config) { 855 updatePendingConfiguration(config); 856 sendMessage(H.CONFIGURATION_CHANGED, config); 857 } 858 859 public void updateTimeZone() { 860 TimeZone.setDefault(null); 861 } 862 863 public void clearDnsCache() { 864 // a non-standard API to get this to libcore 865 InetAddress.clearDnsCache(); 866 // Allow libcore to perform the necessary actions as it sees fit upon a network 867 // configuration change. 868 NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged(); 869 } 870 871 public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) { 872 final ConnectivityManager cm = ConnectivityManager.from(getSystemContext()); 873 final Network network = cm.getBoundNetworkForProcess(); 874 if (network != null) { 875 Proxy.setHttpProxySystemProperty(cm.getDefaultProxy()); 876 } else { 877 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl); 878 } 879 } 880 881 public void processInBackground() { 882 mH.removeMessages(H.GC_WHEN_IDLE); 883 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE)); 884 } 885 886 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) { 887 DumpComponentInfo data = new DumpComponentInfo(); 888 try { 889 data.fd = ParcelFileDescriptor.dup(fd); 890 data.token = servicetoken; 891 data.args = args; 892 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/); 893 } catch (IOException e) { 894 Slog.w(TAG, "dumpService failed", e); 895 } 896 } 897 898 // This function exists to make sure all receiver dispatching is 899 // correctly ordered, since these are one-way calls and the binder driver 900 // applies transaction ordering per object for such calls. 901 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, 902 int resultCode, String dataStr, Bundle extras, boolean ordered, 903 boolean sticky, int sendingUser, int processState) throws RemoteException { 904 updateProcessState(processState, false); 905 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, 906 sticky, sendingUser); 907 } 908 909 @Override 910 public void scheduleLowMemory() { 911 sendMessage(H.LOW_MEMORY, null); 912 } 913 914 @Override 915 public void scheduleActivityConfigurationChanged( 916 IBinder token, Configuration overrideConfig, boolean reportToActivity) { 917 sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, 918 new ActivityConfigChangeData(token, overrideConfig), reportToActivity ? 1 : 0); 919 } 920 921 @Override 922 public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 923 sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType); 924 } 925 926 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) { 927 DumpHeapData dhd = new DumpHeapData(); 928 dhd.path = path; 929 dhd.fd = fd; 930 sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/); 931 } 932 933 public void setSchedulingGroup(int group) { 934 // Note: do this immediately, since going into the foreground 935 // should happen regardless of what pending work we have to do 936 // and the activity manager will wait for us to report back that 937 // we are done before sending us to the background. 938 try { 939 Process.setProcessGroup(Process.myPid(), group); 940 } catch (Exception e) { 941 Slog.w(TAG, "Failed setting process group to " + group, e); 942 } 943 } 944 945 public void dispatchPackageBroadcast(int cmd, String[] packages) { 946 sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd); 947 } 948 949 public void scheduleCrash(String msg) { 950 sendMessage(H.SCHEDULE_CRASH, msg); 951 } 952 953 public void dumpActivity(FileDescriptor fd, IBinder activitytoken, 954 String prefix, String[] args) { 955 DumpComponentInfo data = new DumpComponentInfo(); 956 try { 957 data.fd = ParcelFileDescriptor.dup(fd); 958 data.token = activitytoken; 959 data.prefix = prefix; 960 data.args = args; 961 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/); 962 } catch (IOException e) { 963 Slog.w(TAG, "dumpActivity failed", e); 964 } 965 } 966 967 public void dumpProvider(FileDescriptor fd, IBinder providertoken, 968 String[] args) { 969 DumpComponentInfo data = new DumpComponentInfo(); 970 try { 971 data.fd = ParcelFileDescriptor.dup(fd); 972 data.token = providertoken; 973 data.args = args; 974 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/); 975 } catch (IOException e) { 976 Slog.w(TAG, "dumpProvider failed", e); 977 } 978 } 979 980 @Override 981 public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, 982 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, 983 boolean dumpUnreachable, String[] args) { 984 FileOutputStream fout = new FileOutputStream(fd); 985 PrintWriter pw = new FastPrintWriter(fout); 986 try { 987 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable); 988 } finally { 989 pw.flush(); 990 } 991 } 992 993 private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 994 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable) { 995 long nativeMax = Debug.getNativeHeapSize() / 1024; 996 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; 997 long nativeFree = Debug.getNativeHeapFreeSize() / 1024; 998 999 Runtime runtime = Runtime.getRuntime(); 1000 runtime.gc(); // Do GC since countInstancesOfClass counts unreachable objects. 1001 long dalvikMax = runtime.totalMemory() / 1024; 1002 long dalvikFree = runtime.freeMemory() / 1024; 1003 long dalvikAllocated = dalvikMax - dalvikFree; 1004 long viewInstanceCount = ViewDebug.getViewInstanceCount(); 1005 long viewRootInstanceCount = ViewDebug.getViewRootImplCount(); 1006 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class); 1007 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class); 1008 int globalAssetCount = AssetManager.getGlobalAssetCount(); 1009 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount(); 1010 int binderLocalObjectCount = Debug.getBinderLocalObjectCount(); 1011 int binderProxyObjectCount = Debug.getBinderProxyObjectCount(); 1012 int binderDeathObjectCount = Debug.getBinderDeathObjectCount(); 1013 long parcelSize = Parcel.getGlobalAllocSize(); 1014 long parcelCount = Parcel.getGlobalAllocCount(); 1015 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class); 1016 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo(); 1017 1018 dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, 1019 Process.myPid(), 1020 (mBoundApplication != null) ? mBoundApplication.processName : "unknown", 1021 nativeMax, nativeAllocated, nativeFree, 1022 dalvikMax, dalvikAllocated, dalvikFree); 1023 1024 if (checkin) { 1025 // NOTE: if you change anything significant below, also consider changing 1026 // ACTIVITY_THREAD_CHECKIN_VERSION. 1027 1028 // Object counts 1029 pw.print(viewInstanceCount); pw.print(','); 1030 pw.print(viewRootInstanceCount); pw.print(','); 1031 pw.print(appContextInstanceCount); pw.print(','); 1032 pw.print(activityInstanceCount); pw.print(','); 1033 1034 pw.print(globalAssetCount); pw.print(','); 1035 pw.print(globalAssetManagerCount); pw.print(','); 1036 pw.print(binderLocalObjectCount); pw.print(','); 1037 pw.print(binderProxyObjectCount); pw.print(','); 1038 1039 pw.print(binderDeathObjectCount); pw.print(','); 1040 pw.print(openSslSocketCount); pw.print(','); 1041 1042 // SQL 1043 pw.print(stats.memoryUsed / 1024); pw.print(','); 1044 pw.print(stats.memoryUsed / 1024); pw.print(','); 1045 pw.print(stats.pageCacheOverflow / 1024); pw.print(','); 1046 pw.print(stats.largestMemAlloc / 1024); 1047 for (int i = 0; i < stats.dbStats.size(); i++) { 1048 DbStats dbStats = stats.dbStats.get(i); 1049 pw.print(','); pw.print(dbStats.dbName); 1050 pw.print(','); pw.print(dbStats.pageSize); 1051 pw.print(','); pw.print(dbStats.dbSize); 1052 pw.print(','); pw.print(dbStats.lookaside); 1053 pw.print(','); pw.print(dbStats.cache); 1054 pw.print(','); pw.print(dbStats.cache); 1055 } 1056 pw.println(); 1057 1058 return; 1059 } 1060 1061 pw.println(" "); 1062 pw.println(" Objects"); 1063 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:", 1064 viewRootInstanceCount); 1065 1066 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount, 1067 "Activities:", activityInstanceCount); 1068 1069 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount, 1070 "AssetManagers:", globalAssetManagerCount); 1071 1072 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount, 1073 "Proxy Binders:", binderProxyObjectCount); 1074 printRow(pw, TWO_COUNT_COLUMNS, "Parcel memory:", parcelSize/1024, 1075 "Parcel count:", parcelCount); 1076 printRow(pw, TWO_COUNT_COLUMNS, "Death Recipients:", binderDeathObjectCount, 1077 "OpenSSL Sockets:", openSslSocketCount); 1078 1079 // SQLite mem info 1080 pw.println(" "); 1081 pw.println(" SQL"); 1082 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024); 1083 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:", 1084 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024); 1085 pw.println(" "); 1086 int N = stats.dbStats.size(); 1087 if (N > 0) { 1088 pw.println(" DATABASES"); 1089 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache", 1090 "Dbname"); 1091 for (int i = 0; i < N; i++) { 1092 DbStats dbStats = stats.dbStats.get(i); 1093 printRow(pw, DB_INFO_FORMAT, 1094 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ", 1095 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ", 1096 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ", 1097 dbStats.cache, dbStats.dbName); 1098 } 1099 } 1100 1101 // Asset details. 1102 String assetAlloc = AssetManager.getAssetAllocations(); 1103 if (assetAlloc != null) { 1104 pw.println(" "); 1105 pw.println(" Asset Allocations"); 1106 pw.print(assetAlloc); 1107 } 1108 1109 // Unreachable native memory 1110 if (dumpUnreachable) { 1111 boolean showContents = ((mBoundApplication != null) 1112 && ((mBoundApplication.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0)) 1113 || android.os.Build.IS_DEBUGGABLE; 1114 pw.println(" "); 1115 pw.println(" Unreachable memory"); 1116 pw.print(Debug.getUnreachableMemory(100, showContents)); 1117 } 1118 } 1119 1120 @Override 1121 public void dumpGfxInfo(FileDescriptor fd, String[] args) { 1122 dumpGraphicsInfo(fd); 1123 WindowManagerGlobal.getInstance().dumpGfxInfo(fd, args); 1124 } 1125 1126 private void dumpDatabaseInfo(FileDescriptor fd, String[] args) { 1127 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd)); 1128 PrintWriterPrinter printer = new PrintWriterPrinter(pw); 1129 SQLiteDebug.dump(printer, args); 1130 pw.flush(); 1131 } 1132 1133 @Override 1134 public void dumpDbInfo(final FileDescriptor fd, final String[] args) { 1135 if (mSystemThread) { 1136 // Ensure this invocation is asynchronous to prevent 1137 // writer waiting due to buffer cannot be consumed. 1138 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() { 1139 @Override 1140 public void run() { 1141 dumpDatabaseInfo(fd, args); 1142 } 1143 }); 1144 } else { 1145 dumpDatabaseInfo(fd, args); 1146 } 1147 } 1148 1149 @Override 1150 public void unstableProviderDied(IBinder provider) { 1151 sendMessage(H.UNSTABLE_PROVIDER_DIED, provider); 1152 } 1153 1154 @Override 1155 public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, 1156 int requestType) { 1157 RequestAssistContextExtras cmd = new RequestAssistContextExtras(); 1158 cmd.activityToken = activityToken; 1159 cmd.requestToken = requestToken; 1160 cmd.requestType = requestType; 1161 sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd); 1162 } 1163 1164 public void setCoreSettings(Bundle coreSettings) { 1165 sendMessage(H.SET_CORE_SETTINGS, coreSettings); 1166 } 1167 1168 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) { 1169 UpdateCompatibilityData ucd = new UpdateCompatibilityData(); 1170 ucd.pkg = pkg; 1171 ucd.info = info; 1172 sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd); 1173 } 1174 1175 public void scheduleTrimMemory(int level) { 1176 sendMessage(H.TRIM_MEMORY, null, level); 1177 } 1178 1179 public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 1180 sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0); 1181 } 1182 1183 public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options) { 1184 sendMessage(H.ON_NEW_ACTIVITY_OPTIONS, 1185 new Pair<IBinder, ActivityOptions>(token, options)); 1186 } 1187 1188 public void setProcessState(int state) { 1189 updateProcessState(state, true); 1190 } 1191 1192 public void updateProcessState(int processState, boolean fromIpc) { 1193 synchronized (this) { 1194 if (mLastProcessState != processState) { 1195 mLastProcessState = processState; 1196 // Update Dalvik state based on ActivityManager.PROCESS_STATE_* constants. 1197 final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0; 1198 final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1; 1199 int dalvikProcessState = DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE; 1200 // TODO: Tune this since things like gmail sync are important background but not jank perceptible. 1201 if (processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 1202 dalvikProcessState = DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE; 1203 } 1204 VMRuntime.getRuntime().updateProcessState(dalvikProcessState); 1205 if (false) { 1206 Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState 1207 + (fromIpc ? " (from ipc": "")); 1208 } 1209 } 1210 } 1211 } 1212 1213 @Override 1214 public void scheduleInstallProvider(ProviderInfo provider) { 1215 sendMessage(H.INSTALL_PROVIDER, provider); 1216 } 1217 1218 @Override 1219 public final void updateTimePrefs(boolean is24Hour) { 1220 DateFormat.set24HourTimePref(is24Hour); 1221 } 1222 1223 @Override 1224 public void scheduleCancelVisibleBehind(IBinder token) { 1225 sendMessage(H.CANCEL_VISIBLE_BEHIND, token); 1226 } 1227 1228 @Override 1229 public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) { 1230 sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0); 1231 } 1232 1233 @Override 1234 public void scheduleEnterAnimationComplete(IBinder token) { 1235 sendMessage(H.ENTER_ANIMATION_COMPLETE, token); 1236 } 1237 1238 @Override 1239 public void notifyCleartextNetwork(byte[] firstPacket) { 1240 if (StrictMode.vmCleartextNetworkEnabled()) { 1241 StrictMode.onCleartextNetworkDetected(firstPacket); 1242 } 1243 } 1244 1245 @Override 1246 public void startBinderTracking() { 1247 sendMessage(H.START_BINDER_TRACKING, null); 1248 } 1249 1250 @Override 1251 public void stopBinderTrackingAndDump(FileDescriptor fd) { 1252 try { 1253 sendMessage(H.STOP_BINDER_TRACKING_AND_DUMP, ParcelFileDescriptor.dup(fd)); 1254 } catch (IOException e) { 1255 } 1256 } 1257 1258 @Override 1259 public void scheduleMultiWindowChanged(IBinder token, boolean inMultiWindow) 1260 throws RemoteException { 1261 sendMessage(H.MULTI_WINDOW_CHANGED, token, inMultiWindow ? 1 : 0); 1262 } 1263 1264 @Override 1265 public void schedulePictureInPictureChanged(IBinder token, boolean inPip) 1266 throws RemoteException { 1267 sendMessage(H.PICTURE_IN_PICTURE_CHANGED, token, inPip ? 1 : 0); 1268 } 1269 1270 @Override 1271 public void scheduleLocalVoiceInteractionStarted(IBinder token, 1272 IVoiceInteractor voiceInteractor) throws RemoteException { 1273 SomeArgs args = SomeArgs.obtain(); 1274 args.arg1 = token; 1275 args.arg2 = voiceInteractor; 1276 sendMessage(H.LOCAL_VOICE_INTERACTION_STARTED, args); 1277 } 1278 } 1279 1280 private int getLifecycleSeq() { 1281 synchronized (mResourcesManager) { 1282 return mLifecycleSeq++; 1283 } 1284 } 1285 1286 private class H extends Handler { 1287 public static final int LAUNCH_ACTIVITY = 100; 1288 public static final int PAUSE_ACTIVITY = 101; 1289 public static final int PAUSE_ACTIVITY_FINISHING= 102; 1290 public static final int STOP_ACTIVITY_SHOW = 103; 1291 public static final int STOP_ACTIVITY_HIDE = 104; 1292 public static final int SHOW_WINDOW = 105; 1293 public static final int HIDE_WINDOW = 106; 1294 public static final int RESUME_ACTIVITY = 107; 1295 public static final int SEND_RESULT = 108; 1296 public static final int DESTROY_ACTIVITY = 109; 1297 public static final int BIND_APPLICATION = 110; 1298 public static final int EXIT_APPLICATION = 111; 1299 public static final int NEW_INTENT = 112; 1300 public static final int RECEIVER = 113; 1301 public static final int CREATE_SERVICE = 114; 1302 public static final int SERVICE_ARGS = 115; 1303 public static final int STOP_SERVICE = 116; 1304 1305 public static final int CONFIGURATION_CHANGED = 118; 1306 public static final int CLEAN_UP_CONTEXT = 119; 1307 public static final int GC_WHEN_IDLE = 120; 1308 public static final int BIND_SERVICE = 121; 1309 public static final int UNBIND_SERVICE = 122; 1310 public static final int DUMP_SERVICE = 123; 1311 public static final int LOW_MEMORY = 124; 1312 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125; 1313 public static final int RELAUNCH_ACTIVITY = 126; 1314 public static final int PROFILER_CONTROL = 127; 1315 public static final int CREATE_BACKUP_AGENT = 128; 1316 public static final int DESTROY_BACKUP_AGENT = 129; 1317 public static final int SUICIDE = 130; 1318 public static final int REMOVE_PROVIDER = 131; 1319 public static final int ENABLE_JIT = 132; 1320 public static final int DISPATCH_PACKAGE_BROADCAST = 133; 1321 public static final int SCHEDULE_CRASH = 134; 1322 public static final int DUMP_HEAP = 135; 1323 public static final int DUMP_ACTIVITY = 136; 1324 public static final int SLEEPING = 137; 1325 public static final int SET_CORE_SETTINGS = 138; 1326 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139; 1327 public static final int TRIM_MEMORY = 140; 1328 public static final int DUMP_PROVIDER = 141; 1329 public static final int UNSTABLE_PROVIDER_DIED = 142; 1330 public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143; 1331 public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144; 1332 public static final int INSTALL_PROVIDER = 145; 1333 public static final int ON_NEW_ACTIVITY_OPTIONS = 146; 1334 public static final int CANCEL_VISIBLE_BEHIND = 147; 1335 public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148; 1336 public static final int ENTER_ANIMATION_COMPLETE = 149; 1337 public static final int START_BINDER_TRACKING = 150; 1338 public static final int STOP_BINDER_TRACKING_AND_DUMP = 151; 1339 public static final int MULTI_WINDOW_CHANGED = 152; 1340 public static final int PICTURE_IN_PICTURE_CHANGED = 153; 1341 public static final int LOCAL_VOICE_INTERACTION_STARTED = 154; 1342 1343 String codeToString(int code) { 1344 if (DEBUG_MESSAGES) { 1345 switch (code) { 1346 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY"; 1347 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY"; 1348 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING"; 1349 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW"; 1350 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE"; 1351 case SHOW_WINDOW: return "SHOW_WINDOW"; 1352 case HIDE_WINDOW: return "HIDE_WINDOW"; 1353 case RESUME_ACTIVITY: return "RESUME_ACTIVITY"; 1354 case SEND_RESULT: return "SEND_RESULT"; 1355 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY"; 1356 case BIND_APPLICATION: return "BIND_APPLICATION"; 1357 case EXIT_APPLICATION: return "EXIT_APPLICATION"; 1358 case NEW_INTENT: return "NEW_INTENT"; 1359 case RECEIVER: return "RECEIVER"; 1360 case CREATE_SERVICE: return "CREATE_SERVICE"; 1361 case SERVICE_ARGS: return "SERVICE_ARGS"; 1362 case STOP_SERVICE: return "STOP_SERVICE"; 1363 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED"; 1364 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT"; 1365 case GC_WHEN_IDLE: return "GC_WHEN_IDLE"; 1366 case BIND_SERVICE: return "BIND_SERVICE"; 1367 case UNBIND_SERVICE: return "UNBIND_SERVICE"; 1368 case DUMP_SERVICE: return "DUMP_SERVICE"; 1369 case LOW_MEMORY: return "LOW_MEMORY"; 1370 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED"; 1371 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; 1372 case PROFILER_CONTROL: return "PROFILER_CONTROL"; 1373 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT"; 1374 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT"; 1375 case SUICIDE: return "SUICIDE"; 1376 case REMOVE_PROVIDER: return "REMOVE_PROVIDER"; 1377 case ENABLE_JIT: return "ENABLE_JIT"; 1378 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST"; 1379 case SCHEDULE_CRASH: return "SCHEDULE_CRASH"; 1380 case DUMP_HEAP: return "DUMP_HEAP"; 1381 case DUMP_ACTIVITY: return "DUMP_ACTIVITY"; 1382 case SLEEPING: return "SLEEPING"; 1383 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS"; 1384 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO"; 1385 case TRIM_MEMORY: return "TRIM_MEMORY"; 1386 case DUMP_PROVIDER: return "DUMP_PROVIDER"; 1387 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED"; 1388 case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS"; 1389 case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE"; 1390 case INSTALL_PROVIDER: return "INSTALL_PROVIDER"; 1391 case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS"; 1392 case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND"; 1393 case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED"; 1394 case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE"; 1395 case MULTI_WINDOW_CHANGED: return "MULTI_WINDOW_CHANGED"; 1396 case PICTURE_IN_PICTURE_CHANGED: return "PICTURE_IN_PICTURE_CHANGED"; 1397 case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED"; 1398 } 1399 } 1400 return Integer.toString(code); 1401 } 1402 public void handleMessage(Message msg) { 1403 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 1404 switch (msg.what) { 1405 case LAUNCH_ACTIVITY: { 1406 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 1407 final ActivityClientRecord r = (ActivityClientRecord) msg.obj; 1408 1409 r.packageInfo = getPackageInfoNoCheck( 1410 r.activityInfo.applicationInfo, r.compatInfo); 1411 handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); 1412 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1413 } break; 1414 case RELAUNCH_ACTIVITY: { 1415 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); 1416 ActivityClientRecord r = (ActivityClientRecord)msg.obj; 1417 handleRelaunchActivity(r); 1418 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1419 } break; 1420 case PAUSE_ACTIVITY: { 1421 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 1422 SomeArgs args = (SomeArgs) msg.obj; 1423 handlePauseActivity((IBinder) args.arg1, false, 1424 (args.argi1 & USER_LEAVING) != 0, args.argi2, 1425 (args.argi1 & DONT_REPORT) != 0, args.argi3); 1426 maybeSnapshot(); 1427 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1428 } break; 1429 case PAUSE_ACTIVITY_FINISHING: { 1430 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 1431 SomeArgs args = (SomeArgs) msg.obj; 1432 handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0, 1433 args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3); 1434 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1435 } break; 1436 case STOP_ACTIVITY_SHOW: { 1437 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); 1438 SomeArgs args = (SomeArgs) msg.obj; 1439 handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3); 1440 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1441 } break; 1442 case STOP_ACTIVITY_HIDE: { 1443 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); 1444 SomeArgs args = (SomeArgs) msg.obj; 1445 handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3); 1446 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1447 } break; 1448 case SHOW_WINDOW: 1449 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow"); 1450 handleWindowVisibility((IBinder)msg.obj, true); 1451 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1452 break; 1453 case HIDE_WINDOW: 1454 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow"); 1455 handleWindowVisibility((IBinder)msg.obj, false); 1456 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1457 break; 1458 case RESUME_ACTIVITY: 1459 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume"); 1460 SomeArgs args = (SomeArgs) msg.obj; 1461 handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true, 1462 args.argi3, "RESUME_ACTIVITY"); 1463 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1464 break; 1465 case SEND_RESULT: 1466 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult"); 1467 handleSendResult((ResultData)msg.obj); 1468 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1469 break; 1470 case DESTROY_ACTIVITY: 1471 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy"); 1472 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0, 1473 msg.arg2, false); 1474 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1475 break; 1476 case BIND_APPLICATION: 1477 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); 1478 AppBindData data = (AppBindData)msg.obj; 1479 handleBindApplication(data); 1480 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1481 break; 1482 case EXIT_APPLICATION: 1483 if (mInitialApplication != null) { 1484 mInitialApplication.onTerminate(); 1485 } 1486 Looper.myLooper().quit(); 1487 break; 1488 case NEW_INTENT: 1489 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent"); 1490 handleNewIntent((NewIntentData)msg.obj); 1491 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1492 break; 1493 case RECEIVER: 1494 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp"); 1495 handleReceiver((ReceiverData)msg.obj); 1496 maybeSnapshot(); 1497 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1498 break; 1499 case CREATE_SERVICE: 1500 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate"); 1501 handleCreateService((CreateServiceData)msg.obj); 1502 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1503 break; 1504 case BIND_SERVICE: 1505 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind"); 1506 handleBindService((BindServiceData)msg.obj); 1507 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1508 break; 1509 case UNBIND_SERVICE: 1510 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind"); 1511 handleUnbindService((BindServiceData)msg.obj); 1512 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1513 break; 1514 case SERVICE_ARGS: 1515 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart"); 1516 handleServiceArgs((ServiceArgsData)msg.obj); 1517 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1518 break; 1519 case STOP_SERVICE: 1520 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop"); 1521 handleStopService((IBinder)msg.obj); 1522 maybeSnapshot(); 1523 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1524 break; 1525 case CONFIGURATION_CHANGED: 1526 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged"); 1527 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi; 1528 handleConfigurationChanged((Configuration)msg.obj, null); 1529 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1530 break; 1531 case CLEAN_UP_CONTEXT: 1532 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj; 1533 cci.context.performFinalCleanup(cci.who, cci.what); 1534 break; 1535 case GC_WHEN_IDLE: 1536 scheduleGcIdler(); 1537 break; 1538 case DUMP_SERVICE: 1539 handleDumpService((DumpComponentInfo)msg.obj); 1540 break; 1541 case LOW_MEMORY: 1542 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory"); 1543 handleLowMemory(); 1544 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1545 break; 1546 case ACTIVITY_CONFIGURATION_CHANGED: 1547 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged"); 1548 handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj, 1549 msg.arg1 == 1 ? REPORT_TO_ACTIVITY : !REPORT_TO_ACTIVITY); 1550 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1551 break; 1552 case PROFILER_CONTROL: 1553 handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2); 1554 break; 1555 case CREATE_BACKUP_AGENT: 1556 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent"); 1557 handleCreateBackupAgent((CreateBackupAgentData)msg.obj); 1558 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1559 break; 1560 case DESTROY_BACKUP_AGENT: 1561 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent"); 1562 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj); 1563 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1564 break; 1565 case SUICIDE: 1566 Process.killProcess(Process.myPid()); 1567 break; 1568 case REMOVE_PROVIDER: 1569 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove"); 1570 completeRemoveProvider((ProviderRefCount)msg.obj); 1571 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1572 break; 1573 case ENABLE_JIT: 1574 ensureJitEnabled(); 1575 break; 1576 case DISPATCH_PACKAGE_BROADCAST: 1577 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage"); 1578 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj); 1579 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1580 break; 1581 case SCHEDULE_CRASH: 1582 throw new RemoteServiceException((String)msg.obj); 1583 case DUMP_HEAP: 1584 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj); 1585 break; 1586 case DUMP_ACTIVITY: 1587 handleDumpActivity((DumpComponentInfo)msg.obj); 1588 break; 1589 case DUMP_PROVIDER: 1590 handleDumpProvider((DumpComponentInfo)msg.obj); 1591 break; 1592 case SLEEPING: 1593 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping"); 1594 handleSleeping((IBinder)msg.obj, msg.arg1 != 0); 1595 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1596 break; 1597 case SET_CORE_SETTINGS: 1598 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings"); 1599 handleSetCoreSettings((Bundle) msg.obj); 1600 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1601 break; 1602 case UPDATE_PACKAGE_COMPATIBILITY_INFO: 1603 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj); 1604 break; 1605 case TRIM_MEMORY: 1606 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory"); 1607 handleTrimMemory(msg.arg1); 1608 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1609 break; 1610 case UNSTABLE_PROVIDER_DIED: 1611 handleUnstableProviderDied((IBinder)msg.obj, false); 1612 break; 1613 case REQUEST_ASSIST_CONTEXT_EXTRAS: 1614 handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj); 1615 break; 1616 case TRANSLUCENT_CONVERSION_COMPLETE: 1617 handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1); 1618 break; 1619 case INSTALL_PROVIDER: 1620 handleInstallProvider((ProviderInfo) msg.obj); 1621 break; 1622 case ON_NEW_ACTIVITY_OPTIONS: 1623 Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj; 1624 onNewActivityOptions(pair.first, pair.second); 1625 break; 1626 case CANCEL_VISIBLE_BEHIND: 1627 handleCancelVisibleBehind((IBinder) msg.obj); 1628 break; 1629 case BACKGROUND_VISIBLE_BEHIND_CHANGED: 1630 handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0); 1631 break; 1632 case ENTER_ANIMATION_COMPLETE: 1633 handleEnterAnimationComplete((IBinder) msg.obj); 1634 break; 1635 case START_BINDER_TRACKING: 1636 handleStartBinderTracking(); 1637 break; 1638 case STOP_BINDER_TRACKING_AND_DUMP: 1639 handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj); 1640 break; 1641 case MULTI_WINDOW_CHANGED: 1642 handleMultiWindowChanged((IBinder) msg.obj, msg.arg1 == 1); 1643 break; 1644 case PICTURE_IN_PICTURE_CHANGED: 1645 handlePictureInPictureChanged((IBinder) msg.obj, msg.arg1 == 1); 1646 break; 1647 case LOCAL_VOICE_INTERACTION_STARTED: 1648 handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1, 1649 (IVoiceInteractor) ((SomeArgs) msg.obj).arg2); 1650 break; 1651 } 1652 Object obj = msg.obj; 1653 if (obj instanceof SomeArgs) { 1654 ((SomeArgs) obj).recycle(); 1655 } 1656 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); 1657 } 1658 1659 private void maybeSnapshot() { 1660 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) { 1661 // convert the *private* ActivityThread.PackageInfo to *public* known 1662 // android.content.pm.PackageInfo 1663 String packageName = mBoundApplication.info.mPackageName; 1664 android.content.pm.PackageInfo packageInfo = null; 1665 try { 1666 Context context = getSystemContext(); 1667 if(context == null) { 1668 Log.e(TAG, "cannot get a valid context"); 1669 return; 1670 } 1671 PackageManager pm = context.getPackageManager(); 1672 if(pm == null) { 1673 Log.e(TAG, "cannot get a valid PackageManager"); 1674 return; 1675 } 1676 packageInfo = pm.getPackageInfo( 1677 packageName, PackageManager.GET_ACTIVITIES); 1678 } catch (NameNotFoundException e) { 1679 Log.e(TAG, "cannot get package info for " + packageName, e); 1680 } 1681 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo); 1682 } 1683 } 1684 } 1685 1686 private class Idler implements MessageQueue.IdleHandler { 1687 @Override 1688 public final boolean queueIdle() { 1689 ActivityClientRecord a = mNewActivities; 1690 boolean stopProfiling = false; 1691 if (mBoundApplication != null && mProfiler.profileFd != null 1692 && mProfiler.autoStopProfiler) { 1693 stopProfiling = true; 1694 } 1695 if (a != null) { 1696 mNewActivities = null; 1697 IActivityManager am = ActivityManagerNative.getDefault(); 1698 ActivityClientRecord prev; 1699 do { 1700 if (localLOGV) Slog.v( 1701 TAG, "Reporting idle of " + a + 1702 " finished=" + 1703 (a.activity != null && a.activity.mFinished)); 1704 if (a.activity != null && !a.activity.mFinished) { 1705 try { 1706 am.activityIdle(a.token, a.createdConfig, stopProfiling); 1707 a.createdConfig = null; 1708 } catch (RemoteException ex) { 1709 throw ex.rethrowFromSystemServer(); 1710 } 1711 } 1712 prev = a; 1713 a = a.nextIdle; 1714 prev.nextIdle = null; 1715 } while (a != null); 1716 } 1717 if (stopProfiling) { 1718 mProfiler.stopProfiling(); 1719 } 1720 ensureJitEnabled(); 1721 return false; 1722 } 1723 } 1724 1725 final class GcIdler implements MessageQueue.IdleHandler { 1726 @Override 1727 public final boolean queueIdle() { 1728 doGcIfNeeded(); 1729 return false; 1730 } 1731 } 1732 1733 public static ActivityThread currentActivityThread() { 1734 return sCurrentActivityThread; 1735 } 1736 1737 public static boolean isSystem() { 1738 return (sCurrentActivityThread != null) ? sCurrentActivityThread.mSystemThread : false; 1739 } 1740 1741 public static String currentOpPackageName() { 1742 ActivityThread am = currentActivityThread(); 1743 return (am != null && am.getApplication() != null) 1744 ? am.getApplication().getOpPackageName() : null; 1745 } 1746 1747 public static String currentPackageName() { 1748 ActivityThread am = currentActivityThread(); 1749 return (am != null && am.mBoundApplication != null) 1750 ? am.mBoundApplication.appInfo.packageName : null; 1751 } 1752 1753 public static String currentProcessName() { 1754 ActivityThread am = currentActivityThread(); 1755 return (am != null && am.mBoundApplication != null) 1756 ? am.mBoundApplication.processName : null; 1757 } 1758 1759 public static Application currentApplication() { 1760 ActivityThread am = currentActivityThread(); 1761 return am != null ? am.mInitialApplication : null; 1762 } 1763 1764 public static IPackageManager getPackageManager() { 1765 if (sPackageManager != null) { 1766 //Slog.v("PackageManager", "returning cur default = " + sPackageManager); 1767 return sPackageManager; 1768 } 1769 IBinder b = ServiceManager.getService("package"); 1770 //Slog.v("PackageManager", "default service binder = " + b); 1771 sPackageManager = IPackageManager.Stub.asInterface(b); 1772 //Slog.v("PackageManager", "default service = " + sPackageManager); 1773 return sPackageManager; 1774 } 1775 1776 private Configuration mMainThreadConfig = new Configuration(); 1777 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config, 1778 CompatibilityInfo compat) { 1779 if (config == null) { 1780 return null; 1781 } 1782 if (!compat.supportsScreen()) { 1783 mMainThreadConfig.setTo(config); 1784 config = mMainThreadConfig; 1785 compat.applyToConfiguration(displayDensity, config); 1786 } 1787 return config; 1788 } 1789 1790 /** 1791 * Creates the top level resources for the given package. 1792 */ 1793 Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs, 1794 String[] libDirs, int displayId, Configuration overrideConfiguration, 1795 LoadedApk pkgInfo) { 1796 return mResourcesManager.getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs, 1797 displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), 1798 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, 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 r.tmpConfig.setTo(r.newConfig); 3470 if (r.overrideConfig != null) { 3471 r.tmpConfig.updateFrom(r.overrideConfig); 3472 } 3473 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 3474 + r.activityInfo.name + " with newConfig " + r.tmpConfig); 3475 performConfigurationChanged(r.activity, r.tmpConfig, REPORT_TO_ACTIVITY); 3476 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 3477 r.newConfig = null; 3478 } 3479 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 3480 + isForward); 3481 WindowManager.LayoutParams l = r.window.getAttributes(); 3482 if ((l.softInputMode 3483 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 3484 != forwardBit) { 3485 l.softInputMode = (l.softInputMode 3486 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 3487 | forwardBit; 3488 if (r.activity.mVisibleFromClient) { 3489 ViewManager wm = a.getWindowManager(); 3490 View decor = r.window.getDecorView(); 3491 wm.updateViewLayout(decor, l); 3492 } 3493 } 3494 r.activity.mVisibleFromServer = true; 3495 mNumVisibleActivities++; 3496 if (r.activity.mVisibleFromClient) { 3497 r.activity.makeVisible(); 3498 } 3499 } 3500 3501 if (!r.onlyLocalRequest) { 3502 r.nextIdle = mNewActivities; 3503 mNewActivities = r; 3504 if (localLOGV) Slog.v( 3505 TAG, "Scheduling idle handler for " + r); 3506 Looper.myQueue().addIdleHandler(new Idler()); 3507 } 3508 r.onlyLocalRequest = false; 3509 3510 // Tell the activity manager we have resumed. 3511 if (reallyResume) { 3512 try { 3513 ActivityManagerNative.getDefault().activityResumed(token); 3514 } catch (RemoteException ex) { 3515 throw ex.rethrowFromSystemServer(); 3516 } 3517 } 3518 3519 } else { 3520 // If an exception was thrown when trying to resume, then 3521 // just end this activity. 3522 try { 3523 ActivityManagerNative.getDefault() 3524 .finishActivity(token, Activity.RESULT_CANCELED, null, 3525 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 3526 } catch (RemoteException ex) { 3527 throw ex.rethrowFromSystemServer(); 3528 } 3529 } 3530 } 3531 3532 private int mThumbnailWidth = -1; 3533 private int mThumbnailHeight = -1; 3534 private Bitmap mAvailThumbnailBitmap = null; 3535 private Canvas mThumbnailCanvas = null; 3536 3537 private Bitmap createThumbnailBitmap(ActivityClientRecord r) { 3538 Bitmap thumbnail = mAvailThumbnailBitmap; 3539 try { 3540 if (thumbnail == null) { 3541 int w = mThumbnailWidth; 3542 int h; 3543 if (w < 0) { 3544 Resources res = r.activity.getResources(); 3545 int wId = com.android.internal.R.dimen.thumbnail_width; 3546 int hId = com.android.internal.R.dimen.thumbnail_height; 3547 mThumbnailWidth = w = res.getDimensionPixelSize(wId); 3548 mThumbnailHeight = h = res.getDimensionPixelSize(hId); 3549 } else { 3550 h = mThumbnailHeight; 3551 } 3552 3553 // On platforms where we don't want thumbnails, set dims to (0,0) 3554 if ((w > 0) && (h > 0)) { 3555 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 3556 w, h, THUMBNAIL_FORMAT); 3557 thumbnail.eraseColor(0); 3558 } 3559 } 3560 3561 if (thumbnail != null) { 3562 Canvas cv = mThumbnailCanvas; 3563 if (cv == null) { 3564 mThumbnailCanvas = cv = new Canvas(); 3565 } 3566 3567 cv.setBitmap(thumbnail); 3568 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 3569 mAvailThumbnailBitmap = thumbnail; 3570 thumbnail = null; 3571 } 3572 cv.setBitmap(null); 3573 } 3574 3575 } catch (Exception e) { 3576 if (!mInstrumentation.onException(r.activity, e)) { 3577 throw new RuntimeException( 3578 "Unable to create thumbnail of " 3579 + r.intent.getComponent().toShortString() 3580 + ": " + e.toString(), e); 3581 } 3582 thumbnail = null; 3583 } 3584 3585 return thumbnail; 3586 } 3587 3588 private void handlePauseActivity(IBinder token, boolean finished, 3589 boolean userLeaving, int configChanges, boolean dontReport, int seq) { 3590 ActivityClientRecord r = mActivities.get(token); 3591 if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq); 3592 if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) { 3593 return; 3594 } 3595 if (r != null) { 3596 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 3597 if (userLeaving) { 3598 performUserLeavingActivity(r); 3599 } 3600 3601 r.activity.mConfigChangeFlags |= configChanges; 3602 performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity"); 3603 3604 // Make sure any pending writes are now committed. 3605 if (r.isPreHoneycomb()) { 3606 QueuedWork.waitToFinish(); 3607 } 3608 3609 // Tell the activity manager we have paused. 3610 if (!dontReport) { 3611 try { 3612 ActivityManagerNative.getDefault().activityPaused(token); 3613 } catch (RemoteException ex) { 3614 throw ex.rethrowFromSystemServer(); 3615 } 3616 } 3617 mSomeActivitiesChanged = true; 3618 } 3619 } 3620 3621 final void performUserLeavingActivity(ActivityClientRecord r) { 3622 mInstrumentation.callActivityOnUserLeaving(r.activity); 3623 } 3624 3625 final Bundle performPauseActivity(IBinder token, boolean finished, 3626 boolean saveState, String reason) { 3627 ActivityClientRecord r = mActivities.get(token); 3628 return r != null ? performPauseActivity(r, finished, saveState, reason) : null; 3629 } 3630 3631 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 3632 boolean saveState, String reason) { 3633 if (r.paused) { 3634 if (r.activity.mFinished) { 3635 // If we are finishing, we won't call onResume() in certain cases. 3636 // So here we likewise don't want to call onPause() if the activity 3637 // isn't resumed. 3638 return null; 3639 } 3640 RuntimeException e = new RuntimeException( 3641 "Performing pause of activity that is not resumed: " 3642 + r.intent.getComponent().toShortString()); 3643 Slog.e(TAG, e.getMessage(), e); 3644 } 3645 if (finished) { 3646 r.activity.mFinished = true; 3647 } 3648 try { 3649 // Next have the activity save its current state and managed dialogs... 3650 if (!r.activity.mFinished && saveState) { 3651 callCallActivityOnSaveInstanceState(r); 3652 } 3653 // Now we are idle. 3654 r.activity.mCalled = false; 3655 mInstrumentation.callActivityOnPause(r.activity); 3656 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), 3657 r.activity.getComponentName().getClassName(), reason); 3658 if (!r.activity.mCalled) { 3659 throw new SuperNotCalledException( 3660 "Activity " + r.intent.getComponent().toShortString() + 3661 " did not call through to super.onPause()"); 3662 } 3663 3664 } catch (SuperNotCalledException e) { 3665 throw e; 3666 3667 } catch (Exception e) { 3668 if (!mInstrumentation.onException(r.activity, e)) { 3669 throw new RuntimeException( 3670 "Unable to pause activity " 3671 + r.intent.getComponent().toShortString() 3672 + ": " + e.toString(), e); 3673 } 3674 } 3675 r.paused = true; 3676 3677 // Notify any outstanding on paused listeners 3678 ArrayList<OnActivityPausedListener> listeners; 3679 synchronized (mOnPauseListeners) { 3680 listeners = mOnPauseListeners.remove(r.activity); 3681 } 3682 int size = (listeners != null ? listeners.size() : 0); 3683 for (int i = 0; i < size; i++) { 3684 listeners.get(i).onPaused(r.activity); 3685 } 3686 3687 return !r.activity.mFinished && saveState ? r.state : null; 3688 } 3689 3690 final void performStopActivity(IBinder token, boolean saveState, String reason) { 3691 ActivityClientRecord r = mActivities.get(token); 3692 performStopActivityInner(r, null, false, saveState, reason); 3693 } 3694 3695 private static class StopInfo implements Runnable { 3696 ActivityClientRecord activity; 3697 Bundle state; 3698 PersistableBundle persistentState; 3699 CharSequence description; 3700 3701 @Override public void run() { 3702 // Tell activity manager we have been stopped. 3703 try { 3704 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3705 ActivityManagerNative.getDefault().activityStopped( 3706 activity.token, state, persistentState, description); 3707 } catch (RemoteException ex) { 3708 if (ex instanceof TransactionTooLargeException 3709 && activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) { 3710 Log.e(TAG, "App tried sending too much data in instance state", ex); 3711 return; 3712 } 3713 3714 throw ex.rethrowFromSystemServer(); 3715 } 3716 } 3717 } 3718 3719 private static final class ProviderRefCount { 3720 public final IActivityManager.ContentProviderHolder holder; 3721 public final ProviderClientRecord client; 3722 public int stableCount; 3723 public int unstableCount; 3724 3725 // When this is set, the stable and unstable ref counts are 0 and 3726 // we have a pending operation scheduled to remove the ref count 3727 // from the activity manager. On the activity manager we are still 3728 // holding an unstable ref, though it is not reflected in the counts 3729 // here. 3730 public boolean removePending; 3731 3732 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder, 3733 ProviderClientRecord inClient, int sCount, int uCount) { 3734 holder = inHolder; 3735 client = inClient; 3736 stableCount = sCount; 3737 unstableCount = uCount; 3738 } 3739 } 3740 3741 /** 3742 * Core implementation of stopping an activity. Note this is a little 3743 * tricky because the server's meaning of stop is slightly different 3744 * than our client -- for the server, stop means to save state and give 3745 * it the result when it is done, but the window may still be visible. 3746 * For the client, we want to call onStop()/onStart() to indicate when 3747 * the activity's UI visibillity changes. 3748 */ 3749 private void performStopActivityInner(ActivityClientRecord r, 3750 StopInfo info, boolean keepShown, boolean saveState, String reason) { 3751 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3752 if (r != null) { 3753 if (!keepShown && r.stopped) { 3754 if (r.activity.mFinished) { 3755 // If we are finishing, we won't call onResume() in certain 3756 // cases. So here we likewise don't want to call onStop() 3757 // if the activity isn't resumed. 3758 return; 3759 } 3760 RuntimeException e = new RuntimeException( 3761 "Performing stop of activity that is not resumed: " 3762 + r.intent.getComponent().toShortString()); 3763 Slog.e(TAG, e.getMessage(), e); 3764 } 3765 3766 if (info != null) { 3767 try { 3768 // First create a thumbnail for the activity... 3769 // For now, don't create the thumbnail here; we are 3770 // doing that by doing a screen snapshot. 3771 info.description = r.activity.onCreateDescription(); 3772 } catch (Exception e) { 3773 if (!mInstrumentation.onException(r.activity, e)) { 3774 throw new RuntimeException( 3775 "Unable to save state of activity " 3776 + r.intent.getComponent().toShortString() 3777 + ": " + e.toString(), e); 3778 } 3779 } 3780 } 3781 3782 // Next have the activity save its current state and managed dialogs... 3783 if (!r.activity.mFinished && saveState) { 3784 if (r.state == null) { 3785 callCallActivityOnSaveInstanceState(r); 3786 } 3787 } 3788 3789 if (!keepShown) { 3790 try { 3791 // Now we are idle. 3792 r.activity.performStop(false /*preserveWindow*/); 3793 } catch (Exception e) { 3794 if (!mInstrumentation.onException(r.activity, e)) { 3795 throw new RuntimeException( 3796 "Unable to stop activity " 3797 + r.intent.getComponent().toShortString() 3798 + ": " + e.toString(), e); 3799 } 3800 } 3801 r.stopped = true; 3802 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(), 3803 r.activity.getComponentName().getClassName(), reason); 3804 } 3805 3806 r.paused = true; 3807 } 3808 } 3809 3810 private void updateVisibility(ActivityClientRecord r, boolean show) { 3811 View v = r.activity.mDecor; 3812 if (v != null) { 3813 if (show) { 3814 if (!r.activity.mVisibleFromServer) { 3815 r.activity.mVisibleFromServer = true; 3816 mNumVisibleActivities++; 3817 if (r.activity.mVisibleFromClient) { 3818 r.activity.makeVisible(); 3819 } 3820 } 3821 if (r.newConfig != null) { 3822 r.tmpConfig.setTo(r.newConfig); 3823 if (r.overrideConfig != null) { 3824 r.tmpConfig.updateFrom(r.overrideConfig); 3825 } 3826 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 3827 + r.activityInfo.name + " with new config " + r.tmpConfig); 3828 performConfigurationChanged(r.activity, r.tmpConfig, REPORT_TO_ACTIVITY); 3829 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 3830 r.newConfig = null; 3831 } 3832 } else { 3833 if (r.activity.mVisibleFromServer) { 3834 r.activity.mVisibleFromServer = false; 3835 mNumVisibleActivities--; 3836 v.setVisibility(View.INVISIBLE); 3837 } 3838 } 3839 } 3840 } 3841 3842 private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) { 3843 ActivityClientRecord r = mActivities.get(token); 3844 if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) { 3845 return; 3846 } 3847 r.activity.mConfigChangeFlags |= configChanges; 3848 3849 StopInfo info = new StopInfo(); 3850 performStopActivityInner(r, info, show, true, "handleStopActivity"); 3851 3852 if (localLOGV) Slog.v( 3853 TAG, "Finishing stop of " + r + ": show=" + show 3854 + " win=" + r.window); 3855 3856 updateVisibility(r, show); 3857 3858 // Make sure any pending writes are now committed. 3859 if (!r.isPreHoneycomb()) { 3860 QueuedWork.waitToFinish(); 3861 } 3862 3863 // Schedule the call to tell the activity manager we have 3864 // stopped. We don't do this immediately, because we want to 3865 // have a chance for any other pending work (in particular memory 3866 // trim requests) to complete before you tell the activity 3867 // manager to proceed and allow us to go fully into the background. 3868 info.activity = r; 3869 info.state = r.state; 3870 info.persistentState = r.persistentState; 3871 mH.post(info); 3872 mSomeActivitiesChanged = true; 3873 } 3874 3875 private static boolean checkAndUpdateLifecycleSeq(int seq, ActivityClientRecord r, 3876 String action) { 3877 if (r == null) { 3878 return true; 3879 } 3880 if (seq < r.lastProcessedSeq) { 3881 if (DEBUG_ORDER) Slog.d(TAG, action + " for " + r + " ignored, because seq=" + seq 3882 + " < mCurrentLifecycleSeq=" + r.lastProcessedSeq); 3883 return false; 3884 } 3885 r.lastProcessedSeq = seq; 3886 return true; 3887 } 3888 3889 final void performRestartActivity(IBinder token) { 3890 ActivityClientRecord r = mActivities.get(token); 3891 if (r.stopped) { 3892 r.activity.performRestart(); 3893 r.stopped = false; 3894 } 3895 } 3896 3897 private void handleWindowVisibility(IBinder token, boolean show) { 3898 ActivityClientRecord r = mActivities.get(token); 3899 3900 if (r == null) { 3901 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 3902 return; 3903 } 3904 3905 if (!show && !r.stopped) { 3906 performStopActivityInner(r, null, show, false, "handleWindowVisibility"); 3907 } else if (show && r.stopped) { 3908 // If we are getting ready to gc after going to the background, well 3909 // we are back active so skip it. 3910 unscheduleGcIdler(); 3911 3912 r.activity.performRestart(); 3913 r.stopped = false; 3914 } 3915 if (r.activity.mDecor != null) { 3916 if (false) Slog.v( 3917 TAG, "Handle window " + r + " visibility: " + show); 3918 updateVisibility(r, show); 3919 } 3920 mSomeActivitiesChanged = true; 3921 } 3922 3923 private void handleSleeping(IBinder token, boolean sleeping) { 3924 ActivityClientRecord r = mActivities.get(token); 3925 3926 if (r == null) { 3927 Log.w(TAG, "handleSleeping: no activity for token " + token); 3928 return; 3929 } 3930 3931 if (sleeping) { 3932 if (!r.stopped && !r.isPreHoneycomb()) { 3933 try { 3934 // Now we are idle. 3935 r.activity.performStop(false /*preserveWindow*/); 3936 } catch (Exception e) { 3937 if (!mInstrumentation.onException(r.activity, e)) { 3938 throw new RuntimeException( 3939 "Unable to stop activity " 3940 + r.intent.getComponent().toShortString() 3941 + ": " + e.toString(), e); 3942 } 3943 } 3944 r.stopped = true; 3945 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(), 3946 r.activity.getComponentName().getClassName(), "sleeping"); 3947 } 3948 3949 // Make sure any pending writes are now committed. 3950 if (!r.isPreHoneycomb()) { 3951 QueuedWork.waitToFinish(); 3952 } 3953 3954 // Tell activity manager we slept. 3955 try { 3956 ActivityManagerNative.getDefault().activitySlept(r.token); 3957 } catch (RemoteException ex) { 3958 throw ex.rethrowFromSystemServer(); 3959 } 3960 } else { 3961 if (r.stopped && r.activity.mVisibleFromServer) { 3962 r.activity.performRestart(); 3963 r.stopped = false; 3964 } 3965 } 3966 } 3967 3968 private void handleSetCoreSettings(Bundle coreSettings) { 3969 synchronized (mResourcesManager) { 3970 mCoreSettings = coreSettings; 3971 } 3972 onCoreSettingsChange(); 3973 } 3974 3975 private void onCoreSettingsChange() { 3976 boolean debugViewAttributes = 3977 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 3978 if (debugViewAttributes != View.mDebugViewAttributes) { 3979 View.mDebugViewAttributes = debugViewAttributes; 3980 3981 // request all activities to relaunch for the changes to take place 3982 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { 3983 requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false, 3984 false /* preserveWindow */); 3985 } 3986 } 3987 } 3988 3989 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 3990 LoadedApk apk = peekPackageInfo(data.pkg, false); 3991 if (apk != null) { 3992 apk.setCompatibilityInfo(data.info); 3993 } 3994 apk = peekPackageInfo(data.pkg, true); 3995 if (apk != null) { 3996 apk.setCompatibilityInfo(data.info); 3997 } 3998 handleConfigurationChanged(mConfiguration, data.info); 3999 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 4000 } 4001 4002 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 4003 final int N = results.size(); 4004 for (int i=0; i<N; i++) { 4005 ResultInfo ri = results.get(i); 4006 try { 4007 if (ri.mData != null) { 4008 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 4009 ri.mData.prepareToEnterProcess(); 4010 } 4011 if (DEBUG_RESULTS) Slog.v(TAG, 4012 "Delivering result to activity " + r + " : " + ri); 4013 r.activity.dispatchActivityResult(ri.mResultWho, 4014 ri.mRequestCode, ri.mResultCode, ri.mData); 4015 } catch (Exception e) { 4016 if (!mInstrumentation.onException(r.activity, e)) { 4017 throw new RuntimeException( 4018 "Failure delivering result " + ri + " to activity " 4019 + r.intent.getComponent().toShortString() 4020 + ": " + e.toString(), e); 4021 } 4022 } 4023 } 4024 } 4025 4026 private void handleSendResult(ResultData res) { 4027 ActivityClientRecord r = mActivities.get(res.token); 4028 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 4029 if (r != null) { 4030 final boolean resumed = !r.paused; 4031 if (!r.activity.mFinished && r.activity.mDecor != null 4032 && r.hideForNow && resumed) { 4033 // We had hidden the activity because it started another 4034 // one... we have gotten a result back and we are not 4035 // paused, so make sure our window is visible. 4036 updateVisibility(r, true); 4037 } 4038 if (resumed) { 4039 try { 4040 // Now we are idle. 4041 r.activity.mCalled = false; 4042 r.activity.mTemporaryPause = true; 4043 mInstrumentation.callActivityOnPause(r.activity); 4044 if (!r.activity.mCalled) { 4045 throw new SuperNotCalledException( 4046 "Activity " + r.intent.getComponent().toShortString() 4047 + " did not call through to super.onPause()"); 4048 } 4049 } catch (SuperNotCalledException e) { 4050 throw e; 4051 } catch (Exception e) { 4052 if (!mInstrumentation.onException(r.activity, e)) { 4053 throw new RuntimeException( 4054 "Unable to pause activity " 4055 + r.intent.getComponent().toShortString() 4056 + ": " + e.toString(), e); 4057 } 4058 } 4059 } 4060 deliverResults(r, res.results); 4061 if (resumed) { 4062 r.activity.performResume(); 4063 r.activity.mTemporaryPause = false; 4064 } 4065 } 4066 } 4067 4068 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 4069 return performDestroyActivity(token, finishing, 0, false); 4070 } 4071 4072 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 4073 int configChanges, boolean getNonConfigInstance) { 4074 ActivityClientRecord r = mActivities.get(token); 4075 Class<? extends Activity> activityClass = null; 4076 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 4077 if (r != null) { 4078 activityClass = r.activity.getClass(); 4079 r.activity.mConfigChangeFlags |= configChanges; 4080 if (finishing) { 4081 r.activity.mFinished = true; 4082 } 4083 if (!r.paused) { 4084 try { 4085 r.activity.mCalled = false; 4086 mInstrumentation.callActivityOnPause(r.activity); 4087 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), 4088 r.activity.getComponentName().getClassName(), "destroy"); 4089 if (!r.activity.mCalled) { 4090 throw new SuperNotCalledException( 4091 "Activity " + safeToComponentShortString(r.intent) 4092 + " did not call through to super.onPause()"); 4093 } 4094 } catch (SuperNotCalledException e) { 4095 throw e; 4096 } catch (Exception e) { 4097 if (!mInstrumentation.onException(r.activity, e)) { 4098 throw new RuntimeException( 4099 "Unable to pause activity " 4100 + safeToComponentShortString(r.intent) 4101 + ": " + e.toString(), e); 4102 } 4103 } 4104 r.paused = true; 4105 } 4106 if (!r.stopped) { 4107 try { 4108 r.activity.performStop(r.mPreserveWindow); 4109 } catch (SuperNotCalledException e) { 4110 throw e; 4111 } catch (Exception e) { 4112 if (!mInstrumentation.onException(r.activity, e)) { 4113 throw new RuntimeException( 4114 "Unable to stop activity " 4115 + safeToComponentShortString(r.intent) 4116 + ": " + e.toString(), e); 4117 } 4118 } 4119 r.stopped = true; 4120 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(), 4121 r.activity.getComponentName().getClassName(), "destroy"); 4122 } 4123 if (getNonConfigInstance) { 4124 try { 4125 r.lastNonConfigurationInstances 4126 = r.activity.retainNonConfigurationInstances(); 4127 } catch (Exception e) { 4128 if (!mInstrumentation.onException(r.activity, e)) { 4129 throw new RuntimeException( 4130 "Unable to retain activity " 4131 + r.intent.getComponent().toShortString() 4132 + ": " + e.toString(), e); 4133 } 4134 } 4135 } 4136 try { 4137 r.activity.mCalled = false; 4138 mInstrumentation.callActivityOnDestroy(r.activity); 4139 if (!r.activity.mCalled) { 4140 throw new SuperNotCalledException( 4141 "Activity " + safeToComponentShortString(r.intent) + 4142 " did not call through to super.onDestroy()"); 4143 } 4144 if (r.window != null) { 4145 r.window.closeAllPanels(); 4146 } 4147 } catch (SuperNotCalledException e) { 4148 throw e; 4149 } catch (Exception e) { 4150 if (!mInstrumentation.onException(r.activity, e)) { 4151 throw new RuntimeException( 4152 "Unable to destroy activity " + safeToComponentShortString(r.intent) 4153 + ": " + e.toString(), e); 4154 } 4155 } 4156 } 4157 mActivities.remove(token); 4158 StrictMode.decrementExpectedActivityCount(activityClass); 4159 return r; 4160 } 4161 4162 private static String safeToComponentShortString(Intent intent) { 4163 ComponentName component = intent.getComponent(); 4164 return component == null ? "[Unknown]" : component.toShortString(); 4165 } 4166 4167 private void handleDestroyActivity(IBinder token, boolean finishing, 4168 int configChanges, boolean getNonConfigInstance) { 4169 ActivityClientRecord r = performDestroyActivity(token, finishing, 4170 configChanges, getNonConfigInstance); 4171 if (r != null) { 4172 cleanUpPendingRemoveWindows(r, finishing); 4173 WindowManager wm = r.activity.getWindowManager(); 4174 View v = r.activity.mDecor; 4175 if (v != null) { 4176 if (r.activity.mVisibleFromServer) { 4177 mNumVisibleActivities--; 4178 } 4179 IBinder wtoken = v.getWindowToken(); 4180 if (r.activity.mWindowAdded) { 4181 if (r.onlyLocalRequest || r.mPreserveWindow) { 4182 // Hold off on removing this until the new activity's 4183 // window is being added. 4184 r.mPendingRemoveWindow = r.window; 4185 r.mPendingRemoveWindowManager = wm; 4186 if (r.mPreserveWindow) { 4187 // We can only keep the part of the view hierarchy that we control, 4188 // everything else must be removed, because it might not be able to 4189 // behave properly when activity is relaunching. 4190 r.window.clearContentView(); 4191 } 4192 } else { 4193 wm.removeViewImmediate(v); 4194 } 4195 } 4196 if (wtoken != null && r.mPendingRemoveWindow == null) { 4197 WindowManagerGlobal.getInstance().closeAll(wtoken, 4198 r.activity.getClass().getName(), "Activity"); 4199 } 4200 r.activity.mDecor = null; 4201 } 4202 if (r.mPendingRemoveWindow == null) { 4203 // If we are delaying the removal of the activity window, then 4204 // we can't clean up all windows here. Note that we can't do 4205 // so later either, which means any windows that aren't closed 4206 // by the app will leak. Well we try to warning them a lot 4207 // about leaking windows, because that is a bug, so if they are 4208 // using this recreate facility then they get to live with leaks. 4209 WindowManagerGlobal.getInstance().closeAll(token, 4210 r.activity.getClass().getName(), "Activity"); 4211 } 4212 4213 // Mocked out contexts won't be participating in the normal 4214 // process lifecycle, but if we're running with a proper 4215 // ApplicationContext we need to have it tear down things 4216 // cleanly. 4217 Context c = r.activity.getBaseContext(); 4218 if (c instanceof ContextImpl) { 4219 ((ContextImpl) c).scheduleFinalCleanup( 4220 r.activity.getClass().getName(), "Activity"); 4221 } 4222 } 4223 if (finishing) { 4224 try { 4225 ActivityManagerNative.getDefault().activityDestroyed(token); 4226 } catch (RemoteException ex) { 4227 throw ex.rethrowFromSystemServer(); 4228 } 4229 } 4230 mSomeActivitiesChanged = true; 4231 } 4232 4233 /** 4234 * @param preserveWindow Whether the activity should try to reuse the window it created, 4235 * including the decor view after the relaunch. 4236 */ 4237 public final void requestRelaunchActivity(IBinder token, 4238 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 4239 int configChanges, boolean notResumed, Configuration config, 4240 Configuration overrideConfig, boolean fromServer, boolean preserveWindow) { 4241 ActivityClientRecord target = null; 4242 4243 synchronized (mResourcesManager) { 4244 for (int i=0; i<mRelaunchingActivities.size(); i++) { 4245 ActivityClientRecord r = mRelaunchingActivities.get(i); 4246 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r); 4247 if (r.token == token) { 4248 target = r; 4249 if (pendingResults != null) { 4250 if (r.pendingResults != null) { 4251 r.pendingResults.addAll(pendingResults); 4252 } else { 4253 r.pendingResults = pendingResults; 4254 } 4255 } 4256 if (pendingNewIntents != null) { 4257 if (r.pendingIntents != null) { 4258 r.pendingIntents.addAll(pendingNewIntents); 4259 } else { 4260 r.pendingIntents = pendingNewIntents; 4261 } 4262 } 4263 4264 // For each relaunch request, activity manager expects an answer 4265 if (!r.onlyLocalRequest && fromServer) { 4266 try { 4267 ActivityManagerNative.getDefault().activityRelaunched(token); 4268 } catch (RemoteException e) { 4269 throw e.rethrowFromSystemServer(); 4270 } 4271 } 4272 break; 4273 } 4274 } 4275 4276 if (target == null) { 4277 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:" 4278 + fromServer); 4279 target = new ActivityClientRecord(); 4280 target.token = token; 4281 target.pendingResults = pendingResults; 4282 target.pendingIntents = pendingNewIntents; 4283 target.mPreserveWindow = preserveWindow; 4284 if (!fromServer) { 4285 final ActivityClientRecord existing = mActivities.get(token); 4286 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing); 4287 if (existing != null) { 4288 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= " 4289 + existing.paused);; 4290 target.startsNotResumed = existing.paused; 4291 target.overrideConfig = existing.overrideConfig; 4292 } 4293 target.onlyLocalRequest = true; 4294 } 4295 mRelaunchingActivities.add(target); 4296 sendMessage(H.RELAUNCH_ACTIVITY, target); 4297 } 4298 4299 if (fromServer) { 4300 target.startsNotResumed = notResumed; 4301 target.onlyLocalRequest = false; 4302 } 4303 if (config != null) { 4304 target.createdConfig = config; 4305 } 4306 if (overrideConfig != null) { 4307 target.overrideConfig = overrideConfig; 4308 } 4309 target.pendingConfigChanges |= configChanges; 4310 target.relaunchSeq = getLifecycleSeq(); 4311 } 4312 if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this + ", target " 4313 + target + " operation received seq: " + target.relaunchSeq); 4314 } 4315 4316 private void handleRelaunchActivity(ActivityClientRecord tmp) { 4317 // If we are getting ready to gc after going to the background, well 4318 // we are back active so skip it. 4319 unscheduleGcIdler(); 4320 mSomeActivitiesChanged = true; 4321 4322 Configuration changedConfig = null; 4323 int configChanges = 0; 4324 4325 // First: make sure we have the most recent configuration and most 4326 // recent version of the activity, or skip it if some previous call 4327 // had taken a more recent version. 4328 synchronized (mResourcesManager) { 4329 int N = mRelaunchingActivities.size(); 4330 IBinder token = tmp.token; 4331 tmp = null; 4332 for (int i=0; i<N; i++) { 4333 ActivityClientRecord r = mRelaunchingActivities.get(i); 4334 if (r.token == token) { 4335 tmp = r; 4336 configChanges |= tmp.pendingConfigChanges; 4337 mRelaunchingActivities.remove(i); 4338 i--; 4339 N--; 4340 } 4341 } 4342 4343 if (tmp == null) { 4344 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 4345 return; 4346 } 4347 4348 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4349 + tmp.token + " with configChanges=0x" 4350 + Integer.toHexString(configChanges)); 4351 4352 if (mPendingConfiguration != null) { 4353 changedConfig = mPendingConfiguration; 4354 mPendingConfiguration = null; 4355 } 4356 } 4357 4358 if (tmp.lastProcessedSeq > tmp.relaunchSeq) { 4359 Slog.wtf(TAG, "For some reason target: " + tmp + " has lower sequence: " 4360 + tmp.relaunchSeq + " than current sequence: " + tmp.lastProcessedSeq); 4361 } else { 4362 tmp.lastProcessedSeq = tmp.relaunchSeq; 4363 } 4364 if (tmp.createdConfig != null) { 4365 // If the activity manager is passing us its current config, 4366 // assume that is really what we want regardless of what we 4367 // may have pending. 4368 if (mConfiguration == null 4369 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 4370 && mConfiguration.diff(tmp.createdConfig) != 0)) { 4371 if (changedConfig == null 4372 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 4373 changedConfig = tmp.createdConfig; 4374 } 4375 } 4376 } 4377 4378 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4379 + tmp.token + ": changedConfig=" + changedConfig); 4380 4381 // If there was a pending configuration change, execute it first. 4382 if (changedConfig != null) { 4383 mCurDefaultDisplayDpi = changedConfig.densityDpi; 4384 updateDefaultDensity(); 4385 handleConfigurationChanged(changedConfig, null); 4386 } 4387 4388 ActivityClientRecord r = mActivities.get(tmp.token); 4389 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 4390 if (r == null) { 4391 if (!tmp.onlyLocalRequest) { 4392 try { 4393 ActivityManagerNative.getDefault().activityRelaunched(tmp.token); 4394 } catch (RemoteException e) { 4395 throw e.rethrowFromSystemServer(); 4396 } 4397 } 4398 return; 4399 } 4400 4401 r.activity.mConfigChangeFlags |= configChanges; 4402 r.onlyLocalRequest = tmp.onlyLocalRequest; 4403 r.mPreserveWindow = tmp.mPreserveWindow; 4404 r.lastProcessedSeq = tmp.lastProcessedSeq; 4405 r.relaunchSeq = tmp.relaunchSeq; 4406 Intent currentIntent = r.activity.mIntent; 4407 4408 r.activity.mChangingConfigurations = true; 4409 4410 // If we are preserving the main window across relaunches we would also like to preserve 4411 // the children. However the client side view system does not support preserving 4412 // the child views so we notify the window manager to expect these windows to 4413 // be replaced and defer requests to destroy or hide them. This way we can achieve 4414 // visual continuity. It's important that we do this here prior to pause and destroy 4415 // as that is when we may hide or remove the child views. 4416 try { 4417 if (r.mPreserveWindow) { 4418 WindowManagerGlobal.getWindowSession().prepareToReplaceChildren(r.token); 4419 } 4420 } catch (RemoteException e) { 4421 throw e.rethrowFromSystemServer(); 4422 } 4423 4424 4425 // Need to ensure state is saved. 4426 if (!r.paused) { 4427 performPauseActivity(r.token, false, r.isPreHoneycomb(), "handleRelaunchActivity"); 4428 } 4429 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 4430 callCallActivityOnSaveInstanceState(r); 4431 } 4432 4433 handleDestroyActivity(r.token, false, configChanges, true); 4434 4435 r.activity = null; 4436 r.window = null; 4437 r.hideForNow = false; 4438 r.nextIdle = null; 4439 // Merge any pending results and pending intents; don't just replace them 4440 if (tmp.pendingResults != null) { 4441 if (r.pendingResults == null) { 4442 r.pendingResults = tmp.pendingResults; 4443 } else { 4444 r.pendingResults.addAll(tmp.pendingResults); 4445 } 4446 } 4447 if (tmp.pendingIntents != null) { 4448 if (r.pendingIntents == null) { 4449 r.pendingIntents = tmp.pendingIntents; 4450 } else { 4451 r.pendingIntents.addAll(tmp.pendingIntents); 4452 } 4453 } 4454 r.startsNotResumed = tmp.startsNotResumed; 4455 r.overrideConfig = tmp.overrideConfig; 4456 4457 handleLaunchActivity(r, currentIntent, "handleRelaunchActivity"); 4458 4459 if (!tmp.onlyLocalRequest) { 4460 try { 4461 ActivityManagerNative.getDefault().activityRelaunched(r.token); 4462 if (r.window != null) { 4463 r.window.reportActivityRelaunched(); 4464 } 4465 } catch (RemoteException e) { 4466 throw e.rethrowFromSystemServer(); 4467 } 4468 } 4469 } 4470 4471 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) { 4472 r.state = new Bundle(); 4473 r.state.setAllowFds(false); 4474 if (r.isPersistable()) { 4475 r.persistentState = new PersistableBundle(); 4476 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, 4477 r.persistentState); 4478 } else { 4479 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 4480 } 4481 } 4482 4483 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 4484 boolean allActivities, Configuration newConfig) { 4485 ArrayList<ComponentCallbacks2> callbacks 4486 = new ArrayList<ComponentCallbacks2>(); 4487 4488 synchronized (mResourcesManager) { 4489 final int NAPP = mAllApplications.size(); 4490 for (int i=0; i<NAPP; i++) { 4491 callbacks.add(mAllApplications.get(i)); 4492 } 4493 final int NACT = mActivities.size(); 4494 for (int i=0; i<NACT; i++) { 4495 ActivityClientRecord ar = mActivities.valueAt(i); 4496 Activity a = ar.activity; 4497 if (a != null) { 4498 Configuration thisConfig = applyConfigCompatMainThread( 4499 mCurDefaultDisplayDpi, newConfig, 4500 ar.packageInfo.getCompatibilityInfo()); 4501 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 4502 // If the activity is currently resumed, its configuration 4503 // needs to change right now. 4504 callbacks.add(a); 4505 } else if (thisConfig != null) { 4506 // Otherwise, we will tell it about the change 4507 // the next time it is resumed or shown. Note that 4508 // the activity manager may, before then, decide the 4509 // activity needs to be destroyed to handle its new 4510 // configuration. 4511 if (DEBUG_CONFIGURATION) { 4512 Slog.v(TAG, "Setting activity " 4513 + ar.activityInfo.name + " newConfig=" + thisConfig); 4514 } 4515 ar.newConfig = thisConfig; 4516 } 4517 } 4518 } 4519 final int NSVC = mServices.size(); 4520 for (int i=0; i<NSVC; i++) { 4521 callbacks.add(mServices.valueAt(i)); 4522 } 4523 } 4524 synchronized (mProviderMap) { 4525 final int NPRV = mLocalProviders.size(); 4526 for (int i=0; i<NPRV; i++) { 4527 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 4528 } 4529 } 4530 4531 return callbacks; 4532 } 4533 4534 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config, 4535 boolean reportToActivity) { 4536 // Only for Activity objects, check that they actually call up to their 4537 // superclass implementation. ComponentCallbacks2 is an interface, so 4538 // we check the runtime type and act accordingly. 4539 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 4540 if (activity != null) { 4541 activity.mCalled = false; 4542 } 4543 4544 boolean shouldChangeConfig = false; 4545 if ((activity == null) || (activity.mCurrentConfig == null)) { 4546 shouldChangeConfig = true; 4547 } else { 4548 4549 // If the new config is the same as the config this Activity 4550 // is already running with then don't bother calling 4551 // onConfigurationChanged 4552 int diff = activity.mCurrentConfig.diff(config); 4553 if (diff != 0) { 4554 // If this activity doesn't handle any of the config changes then don't bother 4555 // calling onConfigurationChanged as we're going to destroy it. 4556 // Except in the case where the configuration changed on the activity manager side, 4557 // but wasn't big enough to cause a resource change so the activity wasn't destroyed. 4558 // In this case we still want to change the configuration of the activity but not 4559 // report it to the app. 4560 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0 4561 || !reportToActivity) { 4562 shouldChangeConfig = true; 4563 } 4564 } 4565 } 4566 4567 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb 4568 + ": shouldChangeConfig=" + shouldChangeConfig); 4569 if (shouldChangeConfig) { 4570 if (reportToActivity) { 4571 cb.onConfigurationChanged(config); 4572 } 4573 4574 if (activity != null) { 4575 if (reportToActivity && !activity.mCalled) { 4576 throw new SuperNotCalledException( 4577 "Activity " + activity.getLocalClassName() + 4578 " did not call through to super.onConfigurationChanged()"); 4579 } 4580 activity.mConfigChangeFlags = 0; 4581 activity.mCurrentConfig = new Configuration(config); 4582 } 4583 } 4584 } 4585 4586 public final void applyConfigurationToResources(Configuration config) { 4587 synchronized (mResourcesManager) { 4588 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 4589 } 4590 } 4591 4592 final Configuration applyCompatConfiguration(int displayDensity) { 4593 Configuration config = mConfiguration; 4594 if (mCompatConfiguration == null) { 4595 mCompatConfiguration = new Configuration(); 4596 } 4597 mCompatConfiguration.setTo(mConfiguration); 4598 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) { 4599 config = mCompatConfiguration; 4600 } 4601 return config; 4602 } 4603 4604 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 4605 4606 int configDiff = 0; 4607 4608 synchronized (mResourcesManager) { 4609 if (mPendingConfiguration != null) { 4610 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 4611 config = mPendingConfiguration; 4612 mCurDefaultDisplayDpi = config.densityDpi; 4613 updateDefaultDensity(); 4614 } 4615 mPendingConfiguration = null; 4616 } 4617 4618 if (config == null) { 4619 return; 4620 } 4621 4622 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 4623 + config); 4624 4625 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 4626 4627 if (mConfiguration == null) { 4628 mConfiguration = new Configuration(); 4629 } 4630 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 4631 return; 4632 } 4633 4634 configDiff = mConfiguration.updateFrom(config); 4635 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 4636 4637 final Theme systemTheme = getSystemContext().getTheme(); 4638 if ((systemTheme.getChangingConfigurations() & configDiff) != 0) { 4639 systemTheme.rebase(); 4640 } 4641 } 4642 4643 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 4644 4645 freeTextLayoutCachesIfNeeded(configDiff); 4646 4647 if (callbacks != null) { 4648 final int N = callbacks.size(); 4649 for (int i=0; i<N; i++) { 4650 performConfigurationChanged(callbacks.get(i), config, REPORT_TO_ACTIVITY); 4651 } 4652 } 4653 } 4654 4655 static void freeTextLayoutCachesIfNeeded(int configDiff) { 4656 if (configDiff != 0) { 4657 // Ask text layout engine to free its caches if there is a locale change 4658 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 4659 if (hasLocaleConfigChange) { 4660 Canvas.freeTextLayoutCaches(); 4661 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 4662 } 4663 } 4664 } 4665 4666 final void handleActivityConfigurationChanged(ActivityConfigChangeData data, 4667 boolean reportToActivity) { 4668 ActivityClientRecord r = mActivities.get(data.activityToken); 4669 if (r == null || r.activity == null) { 4670 return; 4671 } 4672 4673 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 4674 + r.activityInfo.name + ", with callback=" + reportToActivity); 4675 4676 r.tmpConfig.setTo(mCompatConfiguration); 4677 if (data.overrideConfig != null) { 4678 r.overrideConfig = data.overrideConfig; 4679 r.tmpConfig.updateFrom(data.overrideConfig); 4680 } 4681 performConfigurationChanged(r.activity, r.tmpConfig, reportToActivity); 4682 4683 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); 4684 4685 mSomeActivitiesChanged = true; 4686 } 4687 4688 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 4689 if (start) { 4690 try { 4691 switch (profileType) { 4692 default: 4693 mProfiler.setProfiler(profilerInfo); 4694 mProfiler.startProfiling(); 4695 break; 4696 } 4697 } catch (RuntimeException e) { 4698 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile 4699 + " -- can the process access this path?"); 4700 } finally { 4701 try { 4702 profilerInfo.profileFd.close(); 4703 } catch (IOException e) { 4704 Slog.w(TAG, "Failure closing profile fd", e); 4705 } 4706 } 4707 } else { 4708 switch (profileType) { 4709 default: 4710 mProfiler.stopProfiling(); 4711 break; 4712 } 4713 } 4714 } 4715 4716 /** 4717 * Public entrypoint to stop profiling. This is required to end profiling when the app crashes, 4718 * so that profiler data won't be lost. 4719 * 4720 * @hide 4721 */ 4722 public void stopProfiling() { 4723 mProfiler.stopProfiling(); 4724 } 4725 4726 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 4727 if (managed) { 4728 try { 4729 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 4730 } catch (IOException e) { 4731 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 4732 + " -- can the process access this path?"); 4733 } finally { 4734 try { 4735 dhd.fd.close(); 4736 } catch (IOException e) { 4737 Slog.w(TAG, "Failure closing profile fd", e); 4738 } 4739 } 4740 } else { 4741 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 4742 } 4743 try { 4744 ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path); 4745 } catch (RemoteException e) { 4746 throw e.rethrowFromSystemServer(); 4747 } 4748 } 4749 4750 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 4751 boolean hasPkgInfo = false; 4752 if (packages != null) { 4753 synchronized (mResourcesManager) { 4754 for (int i=packages.length-1; i>=0; i--) { 4755 //Slog.i(TAG, "Cleaning old package: " + packages[i]); 4756 if (!hasPkgInfo) { 4757 WeakReference<LoadedApk> ref; 4758 ref = mPackages.get(packages[i]); 4759 if (ref != null && ref.get() != null) { 4760 hasPkgInfo = true; 4761 } else { 4762 ref = mResourcePackages.get(packages[i]); 4763 if (ref != null && ref.get() != null) { 4764 hasPkgInfo = true; 4765 } 4766 } 4767 } 4768 mPackages.remove(packages[i]); 4769 mResourcePackages.remove(packages[i]); 4770 } 4771 } 4772 } 4773 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, 4774 hasPkgInfo); 4775 } 4776 4777 final void handleLowMemory() { 4778 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4779 4780 final int N = callbacks.size(); 4781 for (int i=0; i<N; i++) { 4782 callbacks.get(i).onLowMemory(); 4783 } 4784 4785 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4786 if (Process.myUid() != Process.SYSTEM_UID) { 4787 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4788 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4789 } 4790 4791 // Ask graphics to free up as much as possible (font/image caches) 4792 Canvas.freeCaches(); 4793 4794 // Ask text layout engine to free also as much as possible 4795 Canvas.freeTextLayoutCaches(); 4796 4797 BinderInternal.forceGc("mem"); 4798 } 4799 4800 final void handleTrimMemory(int level) { 4801 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4802 4803 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4804 4805 final int N = callbacks.size(); 4806 for (int i = 0; i < N; i++) { 4807 callbacks.get(i).onTrimMemory(level); 4808 } 4809 4810 WindowManagerGlobal.getInstance().trimMemory(level); 4811 } 4812 4813 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4814 if (Process.isIsolated()) { 4815 // Isolated processes aren't going to do UI. 4816 return; 4817 } 4818 try { 4819 int uid = Process.myUid(); 4820 String[] packages = getPackageManager().getPackagesForUid(uid); 4821 4822 // If there are several packages in this application we won't 4823 // initialize the graphics disk caches 4824 if (packages != null && packages.length == 1) { 4825 ThreadedRenderer.setupDiskCache(cacheDir); 4826 RenderScriptCacheDir.setupDiskCache(cacheDir); 4827 } 4828 } catch (RemoteException e) { 4829 throw e.rethrowFromSystemServer(); 4830 } 4831 } 4832 4833 // Keep in sync with installd (frameworks/native/cmds/installd/commands.cpp). 4834 private static File getPrimaryProfileFile(String packageName) { 4835 File profileDir = Environment.getDataProfilesDePackageDirectory( 4836 UserHandle.myUserId(), packageName); 4837 return new File(profileDir, "primary.prof"); 4838 } 4839 4840 private static void setupJitProfileSupport(LoadedApk loadedApk, File cacheDir) { 4841 if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) { 4842 return; 4843 } 4844 final ApplicationInfo appInfo = loadedApk.getApplicationInfo(); 4845 final List<String> codePaths = new ArrayList<>(); 4846 if ((appInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) { 4847 codePaths.add(appInfo.sourceDir); 4848 } 4849 if (appInfo.splitSourceDirs != null) { 4850 Collections.addAll(codePaths, appInfo.splitSourceDirs); 4851 } 4852 4853 if (codePaths.isEmpty()) { 4854 // If there are no code paths there's no need to setup a profile file and register with 4855 // the runtime, 4856 return; 4857 } 4858 4859 final File profileFile = getPrimaryProfileFile(loadedApk.mPackageName); 4860 if (!profileFile.exists()) { 4861 FileDescriptor fd = null; 4862 try { 4863 final int permissions = 0600; // read-write for user. 4864 fd = Os.open(profileFile.getAbsolutePath(), OsConstants.O_CREAT, permissions); 4865 Os.fchmod(fd, permissions); 4866 Os.fchown(fd, appInfo.uid, appInfo.uid); 4867 } catch (ErrnoException e) { 4868 Log.v(TAG, "Unable to create jit profile file " + profileFile, e); 4869 try { 4870 Os.unlink(profileFile.getAbsolutePath()); 4871 } catch (ErrnoException unlinkErr) { 4872 Log.v(TAG, "Unable to unlink jit profile file " + profileFile, unlinkErr); 4873 } 4874 return; 4875 } finally { 4876 IoUtils.closeQuietly(fd); 4877 } 4878 } 4879 4880 final File foreignDexProfilesFile = 4881 Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId()); 4882 String foreignDexProfilesPath = null; 4883 if (!foreignDexProfilesFile.exists()) { 4884 Log.v(TAG, "ForeignDexProfilesPath does not exists:" + 4885 foreignDexProfilesFile.getPath()); 4886 } else { 4887 foreignDexProfilesPath = foreignDexProfilesFile.getAbsolutePath(); 4888 } 4889 VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), appInfo.dataDir, 4890 codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesPath); 4891 } 4892 4893 private void updateDefaultDensity() { 4894 final int densityDpi = mCurDefaultDisplayDpi; 4895 if (!mDensityCompatMode 4896 && densityDpi != Configuration.DENSITY_DPI_UNDEFINED 4897 && densityDpi != DisplayMetrics.DENSITY_DEVICE) { 4898 DisplayMetrics.DENSITY_DEVICE = densityDpi; 4899 Bitmap.setDefaultDensity(densityDpi); 4900 } 4901 } 4902 4903 private void handleBindApplication(AppBindData data) { 4904 if (data.trackAllocation) { 4905 DdmVmInternal.enableRecentAllocations(true); 4906 } 4907 4908 mBoundApplication = data; 4909 mConfiguration = new Configuration(data.config); 4910 mCompatConfiguration = new Configuration(data.config); 4911 4912 mProfiler = new Profiler(); 4913 if (data.initProfilerInfo != null) { 4914 mProfiler.profileFile = data.initProfilerInfo.profileFile; 4915 mProfiler.profileFd = data.initProfilerInfo.profileFd; 4916 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; 4917 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; 4918 } 4919 4920 // send up app name; do this *before* waiting for debugger 4921 Process.setArgV0(data.processName); 4922 android.ddm.DdmHandleAppName.setAppName(data.processName, 4923 UserHandle.myUserId()); 4924 4925 if (data.persistent) { 4926 // Persistent processes on low-memory devices do not get to 4927 // use hardware accelerated drawing, since this can add too much 4928 // overhead to the process. 4929 if (!ActivityManager.isHighEndGfx()) { 4930 ThreadedRenderer.disable(false); 4931 } 4932 } 4933 4934 if (mProfiler.profileFd != null) { 4935 mProfiler.startProfiling(); 4936 } 4937 4938 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 4939 // implementation to use the pool executor. Normally, we use the 4940 // serialized executor as the default. This has to happen in the 4941 // main thread so the main looper is set right. 4942 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 4943 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 4944 } 4945 4946 Message.updateCheckRecycle(data.appInfo.targetSdkVersion); 4947 4948 /* 4949 * Before spawning a new process, reset the time zone to be the system time zone. 4950 * This needs to be done because the system time zone could have changed after the 4951 * the spawning of this process. Without doing this this process would have the incorrect 4952 * system time zone. 4953 */ 4954 TimeZone.setDefault(null); 4955 4956 /* 4957 * Initialize the default locales in this process for the reasons we set the time zone. 4958 * 4959 * We do this through ResourcesManager, since we need to do locale negotiation. 4960 */ 4961 mResourcesManager.setDefaultLocalesLocked(data.config.getLocales()); 4962 4963 /* 4964 * Update the system configuration since its preloaded and might not 4965 * reflect configuration changes. The configuration object passed 4966 * in AppBindData can be safely assumed to be up to date 4967 */ 4968 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 4969 mCurDefaultDisplayDpi = data.config.densityDpi; 4970 applyCompatConfiguration(mCurDefaultDisplayDpi); 4971 4972 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4973 4974 /** 4975 * Switch this process to density compatibility mode if needed. 4976 */ 4977 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 4978 == 0) { 4979 mDensityCompatMode = true; 4980 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4981 } 4982 updateDefaultDensity(); 4983 4984 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24)); 4985 DateFormat.set24HourTimePref(is24Hr); 4986 4987 View.mDebugViewAttributes = 4988 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 4989 4990 /** 4991 * For system applications on userdebug/eng builds, log stack 4992 * traces of disk and network access to dropbox for analysis. 4993 */ 4994 if ((data.appInfo.flags & 4995 (ApplicationInfo.FLAG_SYSTEM | 4996 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 4997 StrictMode.conditionallyEnableDebugLogging(); 4998 } 4999 5000 /** 5001 * For apps targetting Honeycomb or later, we don't allow network usage 5002 * on the main event loop / UI thread. This is what ultimately throws 5003 * {@link NetworkOnMainThreadException}. 5004 */ 5005 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) { 5006 StrictMode.enableDeathOnNetwork(); 5007 } 5008 5009 /** 5010 * For apps targetting N or later, we don't allow file:// Uri exposure. 5011 * This is what ultimately throws {@link FileUriExposedException}. 5012 */ 5013 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 5014 StrictMode.enableDeathOnFileUriExposure(); 5015 } 5016 5017 NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted( 5018 (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0); 5019 5020 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 5021 // XXX should have option to change the port. 5022 Debug.changeDebugPort(8100); 5023 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 5024 Slog.w(TAG, "Application " + data.info.getPackageName() 5025 + " is waiting for the debugger on port 8100..."); 5026 5027 IActivityManager mgr = ActivityManagerNative.getDefault(); 5028 try { 5029 mgr.showWaitingForDebugger(mAppThread, true); 5030 } catch (RemoteException ex) { 5031 throw ex.rethrowFromSystemServer(); 5032 } 5033 5034 Debug.waitForDebugger(); 5035 5036 try { 5037 mgr.showWaitingForDebugger(mAppThread, false); 5038 } catch (RemoteException ex) { 5039 throw ex.rethrowFromSystemServer(); 5040 } 5041 5042 } else { 5043 Slog.w(TAG, "Application " + data.info.getPackageName() 5044 + " can be debugged on port 8100..."); 5045 } 5046 } 5047 5048 // Allow application-generated systrace messages if we're debuggable. 5049 boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 5050 Trace.setAppTracingAllowed(isAppDebuggable); 5051 if (isAppDebuggable && data.enableBinderTracking) { 5052 Binder.enableTracing(); 5053 } 5054 5055 /** 5056 * Initialize the default http proxy in this process for the reasons we set the time zone. 5057 */ 5058 final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 5059 if (b != null) { 5060 // In pre-boot mode (doing initial launch to collect password), not 5061 // all system is up. This includes the connectivity service, so don't 5062 // crash if we can't get it. 5063 final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 5064 try { 5065 final ProxyInfo proxyInfo = service.getProxyForNetwork(null); 5066 Proxy.setHttpProxySystemProperty(proxyInfo); 5067 } catch (RemoteException e) { 5068 throw e.rethrowFromSystemServer(); 5069 } 5070 } 5071 5072 // Instrumentation info affects the class loader, so load it before 5073 // setting up the app context. 5074 final InstrumentationInfo ii; 5075 if (data.instrumentationName != null) { 5076 try { 5077 ii = new ApplicationPackageManager(null, getPackageManager()) 5078 .getInstrumentationInfo(data.instrumentationName, 0); 5079 } catch (PackageManager.NameNotFoundException e) { 5080 throw new RuntimeException( 5081 "Unable to find instrumentation info for: " + data.instrumentationName); 5082 } 5083 5084 mInstrumentationPackageName = ii.packageName; 5085 mInstrumentationAppDir = ii.sourceDir; 5086 mInstrumentationSplitAppDirs = ii.splitSourceDirs; 5087 mInstrumentationLibDir = ii.nativeLibraryDir; 5088 mInstrumentedAppDir = data.info.getAppDir(); 5089 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); 5090 mInstrumentedLibDir = data.info.getLibDir(); 5091 } else { 5092 ii = null; 5093 } 5094 5095 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 5096 if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) { 5097 // This cache location probably points at credential-encrypted 5098 // storage which may not be accessible yet; assign it anyway instead 5099 // of pointing at device-encrypted storage. 5100 final File cacheDir = appContext.getCacheDir(); 5101 if (cacheDir != null) { 5102 // Provide a usable directory for temporary files 5103 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 5104 } else { 5105 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property " 5106 + "due to missing cache directory"); 5107 } 5108 5109 // Setup a location to store generated/compiled graphics code and 5110 // JIT profiling data. Note that this data is stored in a 5111 // device-encrypted storage area, so these caches must never contain 5112 // user sensitive user data. 5113 final Context deviceContext = appContext.createDeviceEncryptedStorageContext(); 5114 final File codeCacheDir = deviceContext.getCodeCacheDir(); 5115 if (codeCacheDir != null) { 5116 setupGraphicsSupport(data.info, codeCacheDir); 5117 setupJitProfileSupport(data.info, codeCacheDir); 5118 } else { 5119 Log.e(TAG, "Unable to setupGraphicsSupport and setupJitProfileSupport " + 5120 "due to missing code-cache directory"); 5121 } 5122 5123 // Add the lib dir path to hardware renderer so that vulkan layers 5124 // can be searched for within that directory. 5125 ThreadedRenderer.setLibDir(data.info.getLibDir()); 5126 } 5127 5128 // Install the Network Security Config Provider. This must happen before the application 5129 // code is loaded to prevent issues with instances of TLS objects being created before 5130 // the provider is installed. 5131 NetworkSecurityConfigProvider.install(appContext); 5132 5133 // Continue loading instrumentation. 5134 if (ii != null) { 5135 final ApplicationInfo instrApp = new ApplicationInfo(); 5136 ii.copyTo(instrApp); 5137 instrApp.initForUser(UserHandle.myUserId()); 5138 final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 5139 appContext.getClassLoader(), false, true, false); 5140 final ContextImpl instrContext = ContextImpl.createAppContext(this, pi); 5141 5142 try { 5143 final ClassLoader cl = instrContext.getClassLoader(); 5144 mInstrumentation = (Instrumentation) 5145 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 5146 } catch (Exception e) { 5147 throw new RuntimeException( 5148 "Unable to instantiate instrumentation " 5149 + data.instrumentationName + ": " + e.toString(), e); 5150 } 5151 5152 final ComponentName component = new ComponentName(ii.packageName, ii.name); 5153 mInstrumentation.init(this, instrContext, appContext, component, 5154 data.instrumentationWatcher, data.instrumentationUiAutomationConnection); 5155 5156 if (mProfiler.profileFile != null && !ii.handleProfiling 5157 && mProfiler.profileFd == null) { 5158 mProfiler.handlingProfiling = true; 5159 final File file = new File(mProfiler.profileFile); 5160 file.getParentFile().mkdirs(); 5161 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 5162 } 5163 } else { 5164 mInstrumentation = new Instrumentation(); 5165 } 5166 5167 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 5168 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 5169 } else { 5170 // Small heap, clamp to the current growth limit and let the heap release 5171 // pages after the growth limit to the non growth limit capacity. b/18387825 5172 dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); 5173 } 5174 5175 // Allow disk access during application and provider setup. This could 5176 // block processing ordered broadcasts, but later processing would 5177 // probably end up doing the same disk access. 5178 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 5179 try { 5180 // If the app is being launched for full backup or restore, bring it up in 5181 // a restricted environment with the base application class. 5182 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 5183 mInitialApplication = app; 5184 5185 // don't bring up providers in restricted mode; they may depend on the 5186 // app's custom Application class 5187 if (!data.restrictedBackupMode) { 5188 List<ProviderInfo> providers = data.providers; 5189 if (providers != null) { 5190 installContentProviders(app, providers); 5191 // For process that contains content providers, we want to 5192 // ensure that the JIT is enabled "at some point". 5193 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 5194 } 5195 } 5196 5197 // Do this after providers, since instrumentation tests generally start their 5198 // test thread at this point, and we don't want that racing. 5199 try { 5200 mInstrumentation.onCreate(data.instrumentationArgs); 5201 } 5202 catch (Exception e) { 5203 throw new RuntimeException( 5204 "Exception thrown in onCreate() of " 5205 + data.instrumentationName + ": " + e.toString(), e); 5206 } 5207 5208 try { 5209 mInstrumentation.callApplicationOnCreate(app); 5210 } catch (Exception e) { 5211 if (!mInstrumentation.onException(app, e)) { 5212 throw new RuntimeException( 5213 "Unable to create application " + app.getClass().getName() 5214 + ": " + e.toString(), e); 5215 } 5216 } 5217 } finally { 5218 StrictMode.setThreadPolicy(savedPolicy); 5219 } 5220 } 5221 5222 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 5223 IActivityManager am = ActivityManagerNative.getDefault(); 5224 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 5225 && mProfiler.profileFd == null) { 5226 Debug.stopMethodTracing(); 5227 } 5228 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 5229 // + ", app thr: " + mAppThread); 5230 try { 5231 am.finishInstrumentation(mAppThread, resultCode, results); 5232 } catch (RemoteException ex) { 5233 throw ex.rethrowFromSystemServer(); 5234 } 5235 } 5236 5237 private void installContentProviders( 5238 Context context, List<ProviderInfo> providers) { 5239 final ArrayList<IActivityManager.ContentProviderHolder> results = 5240 new ArrayList<IActivityManager.ContentProviderHolder>(); 5241 5242 for (ProviderInfo cpi : providers) { 5243 if (DEBUG_PROVIDER) { 5244 StringBuilder buf = new StringBuilder(128); 5245 buf.append("Pub "); 5246 buf.append(cpi.authority); 5247 buf.append(": "); 5248 buf.append(cpi.name); 5249 Log.i(TAG, buf.toString()); 5250 } 5251 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 5252 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 5253 if (cph != null) { 5254 cph.noReleaseNeeded = true; 5255 results.add(cph); 5256 } 5257 } 5258 5259 try { 5260 ActivityManagerNative.getDefault().publishContentProviders( 5261 getApplicationThread(), results); 5262 } catch (RemoteException ex) { 5263 throw ex.rethrowFromSystemServer(); 5264 } 5265 } 5266 5267 public final IContentProvider acquireProvider( 5268 Context c, String auth, int userId, boolean stable) { 5269 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 5270 if (provider != null) { 5271 return provider; 5272 } 5273 5274 // There is a possible race here. Another thread may try to acquire 5275 // the same provider at the same time. When this happens, we want to ensure 5276 // that the first one wins. 5277 // Note that we cannot hold the lock while acquiring and installing the 5278 // provider since it might take a long time to run and it could also potentially 5279 // be re-entrant in the case where the provider is in the same process. 5280 IActivityManager.ContentProviderHolder holder = null; 5281 try { 5282 holder = ActivityManagerNative.getDefault().getContentProvider( 5283 getApplicationThread(), auth, userId, stable); 5284 } catch (RemoteException ex) { 5285 throw ex.rethrowFromSystemServer(); 5286 } 5287 if (holder == null) { 5288 Slog.e(TAG, "Failed to find provider info for " + auth); 5289 return null; 5290 } 5291 5292 // Install provider will increment the reference count for us, and break 5293 // any ties in the race. 5294 holder = installProvider(c, holder, holder.info, 5295 true /*noisy*/, holder.noReleaseNeeded, stable); 5296 return holder.provider; 5297 } 5298 5299 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 5300 if (stable) { 5301 prc.stableCount += 1; 5302 if (prc.stableCount == 1) { 5303 // We are acquiring a new stable reference on the provider. 5304 int unstableDelta; 5305 if (prc.removePending) { 5306 // We have a pending remove operation, which is holding the 5307 // last unstable reference. At this point we are converting 5308 // that unstable reference to our new stable reference. 5309 unstableDelta = -1; 5310 // Cancel the removal of the provider. 5311 if (DEBUG_PROVIDER) { 5312 Slog.v(TAG, "incProviderRef: stable " 5313 + "snatched provider from the jaws of death"); 5314 } 5315 prc.removePending = false; 5316 // There is a race! It fails to remove the message, which 5317 // will be handled in completeRemoveProvider(). 5318 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5319 } else { 5320 unstableDelta = 0; 5321 } 5322 try { 5323 if (DEBUG_PROVIDER) { 5324 Slog.v(TAG, "incProviderRef Now stable - " 5325 + prc.holder.info.name + ": unstableDelta=" 5326 + unstableDelta); 5327 } 5328 ActivityManagerNative.getDefault().refContentProvider( 5329 prc.holder.connection, 1, unstableDelta); 5330 } catch (RemoteException e) { 5331 //do nothing content provider object is dead any way 5332 } 5333 } 5334 } else { 5335 prc.unstableCount += 1; 5336 if (prc.unstableCount == 1) { 5337 // We are acquiring a new unstable reference on the provider. 5338 if (prc.removePending) { 5339 // Oh look, we actually have a remove pending for the 5340 // provider, which is still holding the last unstable 5341 // reference. We just need to cancel that to take new 5342 // ownership of the reference. 5343 if (DEBUG_PROVIDER) { 5344 Slog.v(TAG, "incProviderRef: unstable " 5345 + "snatched provider from the jaws of death"); 5346 } 5347 prc.removePending = false; 5348 mH.removeMessages(H.REMOVE_PROVIDER, prc); 5349 } else { 5350 // First unstable ref, increment our count in the 5351 // activity manager. 5352 try { 5353 if (DEBUG_PROVIDER) { 5354 Slog.v(TAG, "incProviderRef: Now unstable - " 5355 + prc.holder.info.name); 5356 } 5357 ActivityManagerNative.getDefault().refContentProvider( 5358 prc.holder.connection, 0, 1); 5359 } catch (RemoteException e) { 5360 //do nothing content provider object is dead any way 5361 } 5362 } 5363 } 5364 } 5365 } 5366 5367 public final IContentProvider acquireExistingProvider( 5368 Context c, String auth, int userId, boolean stable) { 5369 synchronized (mProviderMap) { 5370 final ProviderKey key = new ProviderKey(auth, userId); 5371 final ProviderClientRecord pr = mProviderMap.get(key); 5372 if (pr == null) { 5373 return null; 5374 } 5375 5376 IContentProvider provider = pr.mProvider; 5377 IBinder jBinder = provider.asBinder(); 5378 if (!jBinder.isBinderAlive()) { 5379 // The hosting process of the provider has died; we can't 5380 // use this one. 5381 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 5382 + ": existing object's process dead"); 5383 handleUnstableProviderDiedLocked(jBinder, true); 5384 return null; 5385 } 5386 5387 // Only increment the ref count if we have one. If we don't then the 5388 // provider is not reference counted and never needs to be released. 5389 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5390 if (prc != null) { 5391 incProviderRefLocked(prc, stable); 5392 } 5393 return provider; 5394 } 5395 } 5396 5397 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 5398 if (provider == null) { 5399 return false; 5400 } 5401 5402 IBinder jBinder = provider.asBinder(); 5403 synchronized (mProviderMap) { 5404 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5405 if (prc == null) { 5406 // The provider has no ref count, no release is needed. 5407 return false; 5408 } 5409 5410 boolean lastRef = false; 5411 if (stable) { 5412 if (prc.stableCount == 0) { 5413 if (DEBUG_PROVIDER) Slog.v(TAG, 5414 "releaseProvider: stable ref count already 0, how?"); 5415 return false; 5416 } 5417 prc.stableCount -= 1; 5418 if (prc.stableCount == 0) { 5419 // What we do at this point depends on whether there are 5420 // any unstable refs left: if there are, we just tell the 5421 // activity manager to decrement its stable count; if there 5422 // aren't, we need to enqueue this provider to be removed, 5423 // and convert to holding a single unstable ref while 5424 // doing so. 5425 lastRef = prc.unstableCount == 0; 5426 try { 5427 if (DEBUG_PROVIDER) { 5428 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 5429 + lastRef + " - " + prc.holder.info.name); 5430 } 5431 ActivityManagerNative.getDefault().refContentProvider( 5432 prc.holder.connection, -1, lastRef ? 1 : 0); 5433 } catch (RemoteException e) { 5434 //do nothing content provider object is dead any way 5435 } 5436 } 5437 } else { 5438 if (prc.unstableCount == 0) { 5439 if (DEBUG_PROVIDER) Slog.v(TAG, 5440 "releaseProvider: unstable ref count already 0, how?"); 5441 return false; 5442 } 5443 prc.unstableCount -= 1; 5444 if (prc.unstableCount == 0) { 5445 // If this is the last reference, we need to enqueue 5446 // this provider to be removed instead of telling the 5447 // activity manager to remove it at this point. 5448 lastRef = prc.stableCount == 0; 5449 if (!lastRef) { 5450 try { 5451 if (DEBUG_PROVIDER) { 5452 Slog.v(TAG, "releaseProvider: No longer unstable - " 5453 + prc.holder.info.name); 5454 } 5455 ActivityManagerNative.getDefault().refContentProvider( 5456 prc.holder.connection, 0, -1); 5457 } catch (RemoteException e) { 5458 //do nothing content provider object is dead any way 5459 } 5460 } 5461 } 5462 } 5463 5464 if (lastRef) { 5465 if (!prc.removePending) { 5466 // Schedule the actual remove asynchronously, since we don't know the context 5467 // this will be called in. 5468 // TODO: it would be nice to post a delayed message, so 5469 // if we come back and need the same provider quickly 5470 // we will still have it available. 5471 if (DEBUG_PROVIDER) { 5472 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 5473 + prc.holder.info.name); 5474 } 5475 prc.removePending = true; 5476 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 5477 mH.sendMessage(msg); 5478 } else { 5479 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 5480 } 5481 } 5482 return true; 5483 } 5484 } 5485 5486 final void completeRemoveProvider(ProviderRefCount prc) { 5487 synchronized (mProviderMap) { 5488 if (!prc.removePending) { 5489 // There was a race! Some other client managed to acquire 5490 // the provider before the removal was completed. 5491 // Abort the removal. We will do it later. 5492 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 5493 + "provider still in use"); 5494 return; 5495 } 5496 5497 // More complicated race!! Some client managed to acquire the 5498 // provider and release it before the removal was completed. 5499 // Continue the removal, and abort the next remove message. 5500 prc.removePending = false; 5501 5502 final IBinder jBinder = prc.holder.provider.asBinder(); 5503 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 5504 if (existingPrc == prc) { 5505 mProviderRefCountMap.remove(jBinder); 5506 } 5507 5508 for (int i=mProviderMap.size()-1; i>=0; i--) { 5509 ProviderClientRecord pr = mProviderMap.valueAt(i); 5510 IBinder myBinder = pr.mProvider.asBinder(); 5511 if (myBinder == jBinder) { 5512 mProviderMap.removeAt(i); 5513 } 5514 } 5515 } 5516 5517 try { 5518 if (DEBUG_PROVIDER) { 5519 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 5520 + "removeContentProvider(" + prc.holder.info.name + ")"); 5521 } 5522 ActivityManagerNative.getDefault().removeContentProvider( 5523 prc.holder.connection, false); 5524 } catch (RemoteException e) { 5525 //do nothing content provider object is dead any way 5526 } 5527 } 5528 5529 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 5530 synchronized (mProviderMap) { 5531 handleUnstableProviderDiedLocked(provider, fromClient); 5532 } 5533 } 5534 5535 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 5536 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5537 if (prc != null) { 5538 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 5539 + provider + " " + prc.holder.info.name); 5540 mProviderRefCountMap.remove(provider); 5541 for (int i=mProviderMap.size()-1; i>=0; i--) { 5542 ProviderClientRecord pr = mProviderMap.valueAt(i); 5543 if (pr != null && pr.mProvider.asBinder() == provider) { 5544 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 5545 mProviderMap.removeAt(i); 5546 } 5547 } 5548 5549 if (fromClient) { 5550 // We found out about this due to execution in our client 5551 // code. Tell the activity manager about it now, to ensure 5552 // that the next time we go to do anything with the provider 5553 // it knows it is dead (so we don't race with its death 5554 // notification). 5555 try { 5556 ActivityManagerNative.getDefault().unstableProviderDied( 5557 prc.holder.connection); 5558 } catch (RemoteException e) { 5559 //do nothing content provider object is dead any way 5560 } 5561 } 5562 } 5563 } 5564 5565 final void appNotRespondingViaProvider(IBinder provider) { 5566 synchronized (mProviderMap) { 5567 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5568 if (prc != null) { 5569 try { 5570 ActivityManagerNative.getDefault() 5571 .appNotRespondingViaProvider(prc.holder.connection); 5572 } catch (RemoteException e) { 5573 throw e.rethrowFromSystemServer(); 5574 } 5575 } 5576 } 5577 } 5578 5579 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 5580 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 5581 final String auths[] = holder.info.authority.split(";"); 5582 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 5583 5584 final ProviderClientRecord pcr = new ProviderClientRecord( 5585 auths, provider, localProvider, holder); 5586 for (String auth : auths) { 5587 final ProviderKey key = new ProviderKey(auth, userId); 5588 final ProviderClientRecord existing = mProviderMap.get(key); 5589 if (existing != null) { 5590 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 5591 + " already published as " + auth); 5592 } else { 5593 mProviderMap.put(key, pcr); 5594 } 5595 } 5596 return pcr; 5597 } 5598 5599 /** 5600 * Installs the provider. 5601 * 5602 * Providers that are local to the process or that come from the system server 5603 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 5604 * Other remote providers are reference counted. The initial reference count 5605 * for all reference counted providers is one. Providers that are not reference 5606 * counted do not have a reference count (at all). 5607 * 5608 * This method detects when a provider has already been installed. When this happens, 5609 * it increments the reference count of the existing provider (if appropriate) 5610 * and returns the existing provider. This can happen due to concurrent 5611 * attempts to acquire the same provider. 5612 */ 5613 private IActivityManager.ContentProviderHolder installProvider(Context context, 5614 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 5615 boolean noisy, boolean noReleaseNeeded, boolean stable) { 5616 ContentProvider localProvider = null; 5617 IContentProvider provider; 5618 if (holder == null || holder.provider == null) { 5619 if (DEBUG_PROVIDER || noisy) { 5620 Slog.d(TAG, "Loading provider " + info.authority + ": " 5621 + info.name); 5622 } 5623 Context c = null; 5624 ApplicationInfo ai = info.applicationInfo; 5625 if (context.getPackageName().equals(ai.packageName)) { 5626 c = context; 5627 } else if (mInitialApplication != null && 5628 mInitialApplication.getPackageName().equals(ai.packageName)) { 5629 c = mInitialApplication; 5630 } else { 5631 try { 5632 c = context.createPackageContext(ai.packageName, 5633 Context.CONTEXT_INCLUDE_CODE); 5634 } catch (PackageManager.NameNotFoundException e) { 5635 // Ignore 5636 } 5637 } 5638 if (c == null) { 5639 Slog.w(TAG, "Unable to get context for package " + 5640 ai.packageName + 5641 " while loading content provider " + 5642 info.name); 5643 return null; 5644 } 5645 try { 5646 final java.lang.ClassLoader cl = c.getClassLoader(); 5647 localProvider = (ContentProvider)cl. 5648 loadClass(info.name).newInstance(); 5649 provider = localProvider.getIContentProvider(); 5650 if (provider == null) { 5651 Slog.e(TAG, "Failed to instantiate class " + 5652 info.name + " from sourceDir " + 5653 info.applicationInfo.sourceDir); 5654 return null; 5655 } 5656 if (DEBUG_PROVIDER) Slog.v( 5657 TAG, "Instantiating local provider " + info.name); 5658 // XXX Need to create the correct context for this provider. 5659 localProvider.attachInfo(c, info); 5660 } catch (java.lang.Exception e) { 5661 if (!mInstrumentation.onException(null, e)) { 5662 throw new RuntimeException( 5663 "Unable to get provider " + info.name 5664 + ": " + e.toString(), e); 5665 } 5666 return null; 5667 } 5668 } else { 5669 provider = holder.provider; 5670 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 5671 + info.name); 5672 } 5673 5674 IActivityManager.ContentProviderHolder retHolder; 5675 5676 synchronized (mProviderMap) { 5677 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 5678 + " / " + info.name); 5679 IBinder jBinder = provider.asBinder(); 5680 if (localProvider != null) { 5681 ComponentName cname = new ComponentName(info.packageName, info.name); 5682 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 5683 if (pr != null) { 5684 if (DEBUG_PROVIDER) { 5685 Slog.v(TAG, "installProvider: lost the race, " 5686 + "using existing local provider"); 5687 } 5688 provider = pr.mProvider; 5689 } else { 5690 holder = new IActivityManager.ContentProviderHolder(info); 5691 holder.provider = provider; 5692 holder.noReleaseNeeded = true; 5693 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 5694 mLocalProviders.put(jBinder, pr); 5695 mLocalProvidersByName.put(cname, pr); 5696 } 5697 retHolder = pr.mHolder; 5698 } else { 5699 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5700 if (prc != null) { 5701 if (DEBUG_PROVIDER) { 5702 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 5703 } 5704 // We need to transfer our new reference to the existing 5705 // ref count, releasing the old one... but only if 5706 // release is needed (that is, it is not running in the 5707 // system process). 5708 if (!noReleaseNeeded) { 5709 incProviderRefLocked(prc, stable); 5710 try { 5711 ActivityManagerNative.getDefault().removeContentProvider( 5712 holder.connection, stable); 5713 } catch (RemoteException e) { 5714 //do nothing content provider object is dead any way 5715 } 5716 } 5717 } else { 5718 ProviderClientRecord client = installProviderAuthoritiesLocked( 5719 provider, localProvider, holder); 5720 if (noReleaseNeeded) { 5721 prc = new ProviderRefCount(holder, client, 1000, 1000); 5722 } else { 5723 prc = stable 5724 ? new ProviderRefCount(holder, client, 1, 0) 5725 : new ProviderRefCount(holder, client, 0, 1); 5726 } 5727 mProviderRefCountMap.put(jBinder, prc); 5728 } 5729 retHolder = prc.holder; 5730 } 5731 } 5732 5733 return retHolder; 5734 } 5735 5736 private void attach(boolean system) { 5737 sCurrentActivityThread = this; 5738 mSystemThread = system; 5739 if (!system) { 5740 ViewRootImpl.addFirstDrawHandler(new Runnable() { 5741 @Override 5742 public void run() { 5743 ensureJitEnabled(); 5744 } 5745 }); 5746 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 5747 UserHandle.myUserId()); 5748 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 5749 final IActivityManager mgr = ActivityManagerNative.getDefault(); 5750 try { 5751 mgr.attachApplication(mAppThread); 5752 } catch (RemoteException ex) { 5753 throw ex.rethrowFromSystemServer(); 5754 } 5755 // Watch for getting close to heap limit. 5756 BinderInternal.addGcWatcher(new Runnable() { 5757 @Override public void run() { 5758 if (!mSomeActivitiesChanged) { 5759 return; 5760 } 5761 Runtime runtime = Runtime.getRuntime(); 5762 long dalvikMax = runtime.maxMemory(); 5763 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); 5764 if (dalvikUsed > ((3*dalvikMax)/4)) { 5765 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) 5766 + " total=" + (runtime.totalMemory()/1024) 5767 + " used=" + (dalvikUsed/1024)); 5768 mSomeActivitiesChanged = false; 5769 try { 5770 mgr.releaseSomeActivities(mAppThread); 5771 } catch (RemoteException e) { 5772 throw e.rethrowFromSystemServer(); 5773 } 5774 } 5775 } 5776 }); 5777 } else { 5778 // Don't set application object here -- if the system crashes, 5779 // we can't display an alert, we just want to die die die. 5780 android.ddm.DdmHandleAppName.setAppName("system_process", 5781 UserHandle.myUserId()); 5782 try { 5783 mInstrumentation = new Instrumentation(); 5784 ContextImpl context = ContextImpl.createAppContext( 5785 this, getSystemContext().mPackageInfo); 5786 mInitialApplication = context.mPackageInfo.makeApplication(true, null); 5787 mInitialApplication.onCreate(); 5788 } catch (Exception e) { 5789 throw new RuntimeException( 5790 "Unable to instantiate Application():" + e.toString(), e); 5791 } 5792 } 5793 5794 // add dropbox logging to libcore 5795 DropBox.setReporter(new DropBoxReporter()); 5796 5797 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 5798 @Override 5799 public void onConfigurationChanged(Configuration newConfig) { 5800 synchronized (mResourcesManager) { 5801 // We need to apply this change to the resources 5802 // immediately, because upon returning the view 5803 // hierarchy will be informed about it. 5804 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { 5805 // This actually changed the resources! Tell 5806 // everyone about it. 5807 if (mPendingConfiguration == null || 5808 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 5809 mPendingConfiguration = newConfig; 5810 5811 sendMessage(H.CONFIGURATION_CHANGED, newConfig); 5812 } 5813 } 5814 } 5815 } 5816 @Override 5817 public void onLowMemory() { 5818 } 5819 @Override 5820 public void onTrimMemory(int level) { 5821 } 5822 }); 5823 } 5824 5825 public static ActivityThread systemMain() { 5826 // The system process on low-memory devices do not get to use hardware 5827 // accelerated drawing, since this can add too much overhead to the 5828 // process. 5829 if (!ActivityManager.isHighEndGfx()) { 5830 ThreadedRenderer.disable(true); 5831 } else { 5832 ThreadedRenderer.enableForegroundTrimming(); 5833 } 5834 ActivityThread thread = new ActivityThread(); 5835 thread.attach(true); 5836 return thread; 5837 } 5838 5839 public final void installSystemProviders(List<ProviderInfo> providers) { 5840 if (providers != null) { 5841 installContentProviders(mInitialApplication, providers); 5842 } 5843 } 5844 5845 public int getIntCoreSetting(String key, int defaultValue) { 5846 synchronized (mResourcesManager) { 5847 if (mCoreSettings != null) { 5848 return mCoreSettings.getInt(key, defaultValue); 5849 } 5850 return defaultValue; 5851 } 5852 } 5853 5854 private static class EventLoggingReporter implements EventLogger.Reporter { 5855 @Override 5856 public void report (int code, Object... list) { 5857 EventLog.writeEvent(code, list); 5858 } 5859 } 5860 5861 private class DropBoxReporter implements DropBox.Reporter { 5862 5863 private DropBoxManager dropBox; 5864 5865 public DropBoxReporter() {} 5866 5867 @Override 5868 public void addData(String tag, byte[] data, int flags) { 5869 ensureInitialized(); 5870 dropBox.addData(tag, data, flags); 5871 } 5872 5873 @Override 5874 public void addText(String tag, String data) { 5875 ensureInitialized(); 5876 dropBox.addText(tag, data); 5877 } 5878 5879 private synchronized void ensureInitialized() { 5880 if (dropBox == null) { 5881 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 5882 } 5883 } 5884 } 5885 5886 public static void main(String[] args) { 5887 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); 5888 SamplingProfilerIntegration.start(); 5889 5890 // CloseGuard defaults to true and can be quite spammy. We 5891 // disable it here, but selectively enable it later (via 5892 // StrictMode) on debug builds, but using DropBox, not logs. 5893 CloseGuard.setEnabled(false); 5894 5895 Environment.initForCurrentUser(); 5896 5897 // Set the reporter for event logging in libcore 5898 EventLogger.setReporter(new EventLoggingReporter()); 5899 5900 AndroidKeyStoreProvider.install(); 5901 5902 // Make sure TrustedCertificateStore looks in the right place for CA certificates 5903 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); 5904 TrustedCertificateStore.setDefaultUserDirectory(configDir); 5905 5906 Process.setArgV0("<pre-initialized>"); 5907 5908 Looper.prepareMainLooper(); 5909 5910 ActivityThread thread = new ActivityThread(); 5911 thread.attach(false); 5912 5913 if (sMainThreadHandler == null) { 5914 sMainThreadHandler = thread.getHandler(); 5915 } 5916 5917 if (false) { 5918 Looper.myLooper().setMessageLogging(new 5919 LogPrinter(Log.DEBUG, "ActivityThread")); 5920 } 5921 5922 // End of event ActivityThreadMain. 5923 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5924 Looper.loop(); 5925 5926 throw new RuntimeException("Main thread loop unexpectedly exited"); 5927 } 5928} 5929