Home | History | Annotate | Download | only in base
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 package org.chromium.base;
      6 
      7 import android.app.Activity;
      8 import android.content.ComponentCallbacks2;
      9 import android.content.Context;
     10 import android.content.res.Configuration;
     11 
     12 import org.chromium.base.annotations.CalledByNative;
     13 import org.chromium.base.annotations.MainDex;
     14 
     15 
     16 /**
     17  * This is an internal implementation of the C++ counterpart.
     18  * It registers a ComponentCallbacks2 with the system, and dispatches into
     19  * native for levels that are considered actionable.
     20  */
     21 @MainDex
     22 public class MemoryPressureListener {
     23     /**
     24      * Sending an intent with this action to Chrome will cause it to issue a call to onLowMemory
     25      * thus simulating a low memory situations.
     26      */
     27     private static final String ACTION_LOW_MEMORY = "org.chromium.base.ACTION_LOW_MEMORY";
     28 
     29     /**
     30      * Sending an intent with this action to Chrome will cause it to issue a call to onTrimMemory
     31      * thus simulating a low memory situations.
     32      */
     33     private static final String ACTION_TRIM_MEMORY = "org.chromium.base.ACTION_TRIM_MEMORY";
     34 
     35     /**
     36      * Sending an intent with this action to Chrome will cause it to issue a call to onTrimMemory
     37      * with notification level TRIM_MEMORY_RUNNING_CRITICAL thus simulating a low memory situation
     38      */
     39     private static final String ACTION_TRIM_MEMORY_RUNNING_CRITICAL =
     40             "org.chromium.base.ACTION_TRIM_MEMORY_RUNNING_CRITICAL";
     41 
     42     /**
     43      * Sending an intent with this action to Chrome will cause it to issue a call to onTrimMemory
     44      * with notification level TRIM_MEMORY_MODERATE thus simulating a low memory situation
     45      */
     46     private static final String ACTION_TRIM_MEMORY_MODERATE =
     47             "org.chromium.base.ACTION_TRIM_MEMORY_MODERATE";
     48 
     49     @CalledByNative
     50     private static void registerSystemCallback(Context context) {
     51         context.registerComponentCallbacks(
     52                 new ComponentCallbacks2() {
     53                     @Override
     54                     public void onTrimMemory(int level) {
     55                         maybeNotifyMemoryPresure(level);
     56                     }
     57 
     58                     @Override
     59                     public void onLowMemory() {
     60                         nativeOnMemoryPressure(MemoryPressureLevel.CRITICAL);
     61                     }
     62 
     63                     @Override
     64                     public void onConfigurationChanged(Configuration configuration) {
     65                     }
     66                 });
     67     }
     68 
     69     /**
     70      * Used by applications to simulate a memory pressure signal. By throwing certain intent
     71      * actions.
     72      */
     73     public static boolean handleDebugIntent(Activity activity, String action) {
     74         if (ACTION_LOW_MEMORY.equals(action)) {
     75             simulateLowMemoryPressureSignal(activity);
     76         } else if (ACTION_TRIM_MEMORY.equals(action)) {
     77             simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
     78         } else if (ACTION_TRIM_MEMORY_RUNNING_CRITICAL.equals(action)) {
     79             simulateTrimMemoryPressureSignal(activity,
     80                     ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL);
     81         } else if (ACTION_TRIM_MEMORY_MODERATE.equals(action)) {
     82             simulateTrimMemoryPressureSignal(activity, ComponentCallbacks2.TRIM_MEMORY_MODERATE);
     83         } else {
     84             return false;
     85         }
     86 
     87         return true;
     88     }
     89 
     90     public static void maybeNotifyMemoryPresure(int level) {
     91         if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
     92             nativeOnMemoryPressure(MemoryPressureLevel.CRITICAL);
     93         } else if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
     94                 || level == ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {
     95             // Don't notifiy on TRIM_MEMORY_UI_HIDDEN, since this class only
     96             // dispatches actionable memory pressure signals to native.
     97             nativeOnMemoryPressure(MemoryPressureLevel.MODERATE);
     98         }
     99     }
    100 
    101     private static void simulateLowMemoryPressureSignal(Activity activity) {
    102         // The Application and the Activity each have a list of callbacks they notify when this
    103         // method is called.  Notifying these will simulate the event at the App/Activity level
    104         // as well as trigger the listener bound from native in this process.
    105         activity.getApplication().onLowMemory();
    106         activity.onLowMemory();
    107     }
    108 
    109     private static void simulateTrimMemoryPressureSignal(Activity activity, int level) {
    110         // The Application and the Activity each have a list of callbacks they notify when this
    111         // method is called.  Notifying these will simulate the event at the App/Activity level
    112         // as well as trigger the listener bound from native in this process.
    113         activity.getApplication().onTrimMemory(level);
    114         activity.onTrimMemory(level);
    115     }
    116 
    117     private static native void nativeOnMemoryPressure(int memoryPressureType);
    118 }
    119