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