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