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