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