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