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