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