Some small tweaks to improve memory management.

We now allow processes that currently have stopping activities to
be managed as if they were done stopping, so that memory trimming
can be done before the process goes to the background.  Hopefully
this will reduce cases where the processes goes to the background
and immediately gets killed, but wouldn't have had to be killed if
it had a chance to trim its memory.

Also change window memory trimming to always do the aggressive
trimming when memory is critical, even if not on a low-end device.

And tweak web view trimming to not trim for foreground UI events.

Change-Id: I241b3152b52d09757bd14a202477cf69c9b78786
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 98c4e10..1489b2c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -138,6 +138,7 @@
     private static final boolean DEBUG_BACKUP = true;
     private static final boolean DEBUG_CONFIGURATION = false;
     private static final boolean DEBUG_SERVICE = false;
+    private static final boolean DEBUG_MEMORY_TRIM = false;
     private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
     private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
     private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
@@ -2779,9 +2780,21 @@
         performStopActivityInner(r, null, false, saveState);
     }
 
-    private static class StopInfo {
+    private static class StopInfo implements Runnable {
+        ActivityClientRecord activity;
+        Bundle state;
         Bitmap thumbnail;
         CharSequence description;
+
+        @Override public void run() {
+            // Tell activity manager we have been stopped.
+            try {
+                if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
+                ActivityManagerNative.getDefault().activityStopped(
+                    activity.token, state, thumbnail, description);
+            } catch (RemoteException ex) {
+            }
+        }
     }
 
     private static final class ProviderRefCount {
@@ -2911,12 +2924,14 @@
             QueuedWork.waitToFinish();
         }
 
-        // Tell activity manager we have been stopped.
-        try {
-            ActivityManagerNative.getDefault().activityStopped(
-                r.token, r.state, info.thumbnail, info.description);
-        } catch (RemoteException ex) {
-        }
+        // Schedule the call to tell the activity manager we have
+        // stopped.  We don't do this immediately, because we want to
+        // have a chance for any other pending work (in particular memory
+        // trim requests) to complete before you tell the activity
+        // manager to proceed and allow us to go fully into the background.
+        info.activity = r;
+        info.state = r.state;
+        mH.post(info);
     }
 
     final void performRestartActivity(IBinder token) {
@@ -3749,6 +3764,7 @@
     }
 
     final void handleTrimMemory(int level) {
+        if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
         WindowManagerImpl.getDefault().trimMemory(level);
         ArrayList<ComponentCallbacks2> callbacks;