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