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