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