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