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