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