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