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