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