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