Bug 1106827 - Improve handling of Android memory pressure events r=rnewman
authorJames Willcox <snorp@snorp.net>
Thu, 19 Mar 2015 13:17:05 -0500
changeset 252053 9abdbcdced536f768342a888585762761bbc0843
parent 252052 3b5b22189fcf35c0342190f4fcd289084b000c45
child 252054 f19216bba031c57b063433cbb8f8524b43c8b21f
push id1174
push usernsm.nikhil@gmail.com
push dateSun, 22 Mar 2015 01:24:25 +0000
reviewersrnewman
bugs1106827
milestone39.0a1
Bug 1106827 - Improve handling of Android memory pressure events r=rnewman
mobile/android/base/MemoryMonitor.java
--- a/mobile/android/base/MemoryMonitor.java
+++ b/mobile/android/base/MemoryMonitor.java
@@ -89,28 +89,43 @@ class MemoryMonitor extends BroadcastRec
 
     public void onTrimMemory(int level) {
         Log.d(LOGTAG, "onTrimMemory() notification received with level " + level);
         if (Versions.preICS) {
             // This won't even get called pre-ICS.
             return;
         }
 
-        if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
-            increaseMemoryPressure(MEMORY_PRESSURE_HIGH);
-        } else if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
-            increaseMemoryPressure(MEMORY_PRESSURE_MEDIUM);
-        } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
-            // includes TRIM_MEMORY_BACKGROUND
-            increaseMemoryPressure(MEMORY_PRESSURE_CLEANUP);
-        } else {
-            // levels down here mean gecko is the foreground process so we
-            // should be less aggressive with wiping memory as it may impact
-            // user experience.
-            increaseMemoryPressure(MEMORY_PRESSURE_LOW);
+        if (level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
+            // We seem to get this just by entering the task switcher or hitting the home button.
+            // Seems bogus, because we are the foreground app, or at least not at the end of the LRU list.
+            // Just ignore it, and if there is a real memory pressure event (CRITICAL, MODERATE, etc),
+            // we'll respond appropriately.
+            return;
+        }
+
+        switch (level) {
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
+            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+                // TRIM_MEMORY_MODERATE is the highest level we'll respond to while backgrounded
+                increaseMemoryPressure(MEMORY_PRESSURE_HIGH);
+                break;
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
+                increaseMemoryPressure(MEMORY_PRESSURE_MEDIUM);
+                break;
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
+                increaseMemoryPressure(MEMORY_PRESSURE_LOW);
+                break;
+            case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
+            case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
+                increaseMemoryPressure(MEMORY_PRESSURE_CLEANUP);
+                break;
+            default:
+                Log.d(LOGTAG, "Unhandled onTrimMemory() level " + level);
+                break;
         }
     }
 
     @Override
     public void onReceive(Context context, Intent intent) {
         if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(intent.getAction())) {
             Log.d(LOGTAG, "Device storage is low");
             mStoragePressure = true;
@@ -135,16 +150,18 @@ class MemoryMonitor extends BroadcastRec
             // bump up our level if we're not already higher
             if (mMemoryPressure > level) {
                 return false;
             }
             oldLevel = mMemoryPressure;
             mMemoryPressure = level;
         }
 
+        Log.d(LOGTAG, "increasing memory pressure to " + level);
+
         // since we don't get notifications for when memory pressure is off,
         // we schedule our own timer to slowly back off the memory pressure level.
         // note that this will reset the time to next decrement if the decrementer
         // is already running, which is the desired behaviour because we just got
         // a new low-mem notification.
         mPressureDecrementer.start();
 
         if (oldLevel == level) {