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