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