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