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