Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce86ba86 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Improve handling of low memory.

Now classify background processes into a set of bins of how much
memory they should try to clear.  The last bin also involves
destroying all activities in that process.

Removed the old code for the simulator that is no longer needed
(yay).  The debugging features it had are now integrated into the
regular oom adj code.

Small fixes to load average service.

Change-Id: Ic8df401714b188c73b50dbc8f8e6345b58f1f3a0
parent f7537bcc
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -932,6 +932,10 @@ public final class ActivityThread {
            ucd.info = info;
            queueOrSendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
        }

        public void scheduleTrimMemory(int level) {
            queueOrSendMessage(H.TRIM_MEMORY, level);
        }
    }

    private final class H extends Handler {
@@ -975,6 +979,7 @@ public final class ActivityThread {
        public static final int SLEEPING                = 137;
        public static final int SET_CORE_SETTINGS       = 138;
        public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
        public static final int TRIM_MEMORY             = 140;
        String codeToString(int code) {
            if (DEBUG_MESSAGES) {
                switch (code) {
@@ -1018,6 +1023,7 @@ public final class ActivityThread {
                    case SLEEPING: return "SLEEPING";
                    case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
                    case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
                    case TRIM_MEMORY: return "TRIM_MEMORY";
                }
            }
            return "(unknown)";
@@ -1158,6 +1164,8 @@ public final class ActivityThread {
                    break;
                case UPDATE_PACKAGE_COMPATIBILITY_INFO:
                    handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
                case TRIM_MEMORY:
                    handleTrimMemory(msg.arg1);
            }
            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what);
        }
@@ -3529,6 +3537,9 @@ public final class ActivityThread {
        BinderInternal.forceGc("mem");
    }

    final void handleTrimMemory(int level) {
    }

    private final void handleBindApplication(AppBindData data) {
        mBoundApplication = data;
        mConfiguration = new Configuration(data.config);
+15 −0
Original line number Diff line number Diff line
@@ -478,6 +478,13 @@ public abstract class ApplicationThreadNative extends Binder
            updatePackageCompatibilityInfo(pkg, compat);
            return true;
        }

        case SCHEDULE_TRIM_MEMORY_TRANSACTION: {
            data.enforceInterface(IApplicationThread.descriptor);
            int level = data.readInt();
            scheduleTrimMemory(level);
            return true;
        }
        }

        return super.onTransact(code, data, reply, flags);
@@ -989,4 +996,12 @@ class ApplicationThreadProxy implements IApplicationThread {
        mRemote.transact(UPDATE_PACKAGE_COMPATIBILITY_INFO_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
    }

    public void scheduleTrimMemory(int level) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeInt(level);
        mRemote.transact(SCHEDULE_TRIM_MEMORY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ public interface IApplicationThread extends IInterface {
            throws RemoteException;
    void setCoreSettings(Bundle coreSettings) throws RemoteException;
    void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException;
    void scheduleTrimMemory(int level) throws RemoteException;

    String descriptor = "android.app.IApplicationThread";

@@ -162,4 +163,5 @@ public interface IApplicationThread extends IInterface {
    int SET_HTTP_PROXY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+38;
    int SET_CORE_SETTINGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+39;
    int UPDATE_PACKAGE_COMPATIBILITY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+40;
    int SCHEDULE_TRIM_MEMORY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+41;
}
+12 −0
Original line number Diff line number Diff line
@@ -51,4 +51,16 @@ public interface ComponentCallbacks {
     * The system will perform a gc for you after returning from this method.
     */
    void onLowMemory();

    /** @hide */
    static final int TRIM_MEMORY_COMPLETE = 80;

    /** @hide */
    static final int TRIM_MEMORY_MODERATE = 60;

    /** @hide */
    static final int TRIM_MEMORY_BACKGROUND = 40;

    /** @hide */
    static final int TRIM_MEMORY_INVISIBLE = 20;
}
+37 −22
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.os.Message;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerImpl;

public class LoadAverageService extends Service {
    private View mView;
@@ -91,32 +90,46 @@ public class LoadAverageService extends Service {
            setPadding(4, 4, 4, 4);
            //setBackgroundResource(com.android.internal.R.drawable.load_average_background);

            // Need to scale text size by density...  but we won't do it
            // linearly, because with higher dps it is nice to squeeze the
            // text a bit to fit more of it.  And with lower dps, trying to
            // go much smaller will result in unreadable text.
            int textSize = 10;
            float density = c.getResources().getDisplayMetrics().density;
            if (density < 1) {
                textSize = 9;
            } else {
                textSize = (int)(10*density);
                if (textSize < 10) {
                    textSize = 10;
                }
            }
            mLoadPaint = new Paint();
            mLoadPaint.setAntiAlias(true);
            mLoadPaint.setTextSize(10);
            mLoadPaint.setTextSize(textSize);
            mLoadPaint.setARGB(255, 255, 255, 255);

            mAddedPaint = new Paint();
            mAddedPaint.setAntiAlias(true);
            mAddedPaint.setTextSize(10);
            mAddedPaint.setTextSize(textSize);
            mAddedPaint.setARGB(255, 128, 255, 128);

            mRemovedPaint = new Paint();
            mRemovedPaint.setAntiAlias(true);
            mRemovedPaint.setStrikeThruText(true);
            mRemovedPaint.setTextSize(10);
            mRemovedPaint.setTextSize(textSize);
            mRemovedPaint.setARGB(255, 255, 128, 128);

            mShadowPaint = new Paint();
            mShadowPaint.setAntiAlias(true);
            mShadowPaint.setTextSize(10);
            mShadowPaint.setTextSize(textSize);
            //mShadowPaint.setFakeBoldText(true);
            mShadowPaint.setARGB(192, 0, 0, 0);
            mLoadPaint.setShadowLayer(4, 0, 0, 0xff000000);

            mShadow2Paint = new Paint();
            mShadow2Paint.setAntiAlias(true);
            mShadow2Paint.setTextSize(10);
            mShadow2Paint.setTextSize(textSize);
            //mShadow2Paint.setFakeBoldText(true);
            mShadow2Paint.setARGB(192, 0, 0, 0);
            mLoadPaint.setShadowLayer(2, 0, 0, 0xff000000);
@@ -153,14 +166,16 @@ public class LoadAverageService extends Service {
        }

        @Override
        protected void onMeasure(int widthMeasureSpect, int heightMeasureSpec) {
            setMeasuredDimension(mNeededWidth, mNeededHeight);
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(resolveSize(mNeededWidth, widthMeasureSpec),
                    resolveSize(mNeededHeight, heightMeasureSpec));
        }

        @Override
        public void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            final int W = getWidth();
            final int W = mNeededWidth;
            final int RIGHT = getWidth()-1;

            final Stats stats = mStats;
            final int userTime = stats.getLastUserTime();
@@ -178,7 +193,7 @@ public class LoadAverageService extends Service {
            int systemW = (systemTime*W)/totalTime;
            int irqW = ((iowaitTime+irqTime+softIrqTime)*W)/totalTime;

            int x = W - mPaddingRight;
            int x = RIGHT - mPaddingRight;
            int top = mPaddingTop + 2;
            int bottom = mPaddingTop + mFH - 2;

@@ -196,15 +211,15 @@ public class LoadAverageService extends Service {
            }

            int y = mPaddingTop - (int)mAscent;
            canvas.drawText(stats.mLoadText, W-mPaddingRight-stats.mLoadWidth-1,
            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth-1,
                    y-1, mShadowPaint);
            canvas.drawText(stats.mLoadText, W-mPaddingRight-stats.mLoadWidth-1,
            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth-1,
                    y+1, mShadowPaint);
            canvas.drawText(stats.mLoadText, W-mPaddingRight-stats.mLoadWidth+1,
            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth+1,
                    y-1, mShadow2Paint);
            canvas.drawText(stats.mLoadText, W-mPaddingRight-stats.mLoadWidth+1,
            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth+1,
                    y+1, mShadow2Paint);
            canvas.drawText(stats.mLoadText, W-mPaddingRight-stats.mLoadWidth,
            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth,
                    y, mLoadPaint);

            int N = stats.countWorkingStats();
@@ -216,7 +231,7 @@ public class LoadAverageService extends Service {

                userW = (st.rel_utime*W)/totalTime;
                systemW = (st.rel_stime*W)/totalTime;
                x = W - mPaddingRight;
                x = RIGHT - mPaddingRight;
                if (systemW > 0) {
                    canvas.drawRect(x-systemW, top, x, bottom, mSystemPaint);
                    x -= systemW;
@@ -226,18 +241,18 @@ public class LoadAverageService extends Service {
                    x -= userW;
                }

                canvas.drawText(st.name, W-mPaddingRight-st.nameWidth-1,
                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth-1,
                        y-1, mShadowPaint);
                canvas.drawText(st.name, W-mPaddingRight-st.nameWidth-1,
                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth-1,
                        y+1, mShadowPaint);
                canvas.drawText(st.name, W-mPaddingRight-st.nameWidth+1,
                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth+1,
                        y-1, mShadow2Paint);
                canvas.drawText(st.name, W-mPaddingRight-st.nameWidth+1,
                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth+1,
                        y+1, mShadow2Paint);
                Paint p = mLoadPaint;
                if (st.added) p = mAddedPaint;
                if (st.removed) p = mRemovedPaint;
                canvas.drawText(st.name, W-mPaddingRight-st.nameWidth, y, p);
                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth, y, p);
            }
        }

@@ -270,7 +285,7 @@ public class LoadAverageService extends Service {
        super.onCreate();
        mView = new LoadView(this);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
Loading