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