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