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