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