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

Commit 430392e2 authored by Christopher Lais's avatar Christopher Lais Committed by Steve Kondik
Browse files

Mark uids holding WakeLocks as foreground



MMS and various other service that use internal message queues with
WakeLocks held were getting killed too soon, because the AM thought
they were done processing the request when they had only added it to
their internal queue.

This hack keeps processes belonging to uids with WakeLocks held in
the foreground.

It would be better to tie the WakeLocks to a specific process,
but the PowerManagerService does not seem to keep track of that
information.

Signed-off-by: default avatarChristopher Lais <chris+android@zenthought.org>
parent ca4262bd
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -1167,6 +1167,24 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            overridePendingTransition(token, packageName, enterAnim, exitAnim);
            return true;
        }

        case NOTE_START_WAKELOCK_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            int uid = data.readInt();
            String tag = data.readString();
            int type = data.readInt();
            noteStartWakeLock(uid, tag, type);
            return true;
        }

        case NOTE_STOP_WAKELOCK_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            int uid = data.readInt();
            String tag = data.readString();
            int type = data.readInt();
            noteStopWakeLock(uid, tag, type);
            return true;
        }
        }
        
        return super.onTransact(code, data, reply, flags);
@@ -2565,5 +2583,31 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
    }
    
    public void noteStartWakeLock(int uid, String tag, int type) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(uid);
        data.writeString(tag);
        data.writeInt(type);
        mRemote.transact(NOTE_START_WAKELOCK_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

    public void noteStopWakeLock(int uid, String tag, int type) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(uid);
        data.writeString(tag);
        data.writeInt(type);
        mRemote.transact(NOTE_STOP_WAKELOCK_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

    private IBinder mRemote;
}
+5 −0
Original line number Diff line number Diff line
@@ -288,6 +288,9 @@ public interface IActivityManager extends IInterface {
    public void overridePendingTransition(IBinder token, String packageName,
            int enterAnim, int exitAnim) throws RemoteException;

    public void noteStartWakeLock(int uid, String tag, int type) throws RemoteException;
    public void noteStopWakeLock(int uid, String tag, int type) throws RemoteException;
    
    /*
     * Private non-Binder interfaces
     */
@@ -448,4 +451,6 @@ public interface IActivityManager extends IInterface {
    int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98;
    int START_ACTIVITY_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+99;
    int OVERRIDE_PENDING_TRANSITION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+100;
    int NOTE_START_WAKELOCK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+101;
    int NOTE_STOP_WAKELOCK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+102;
}
+12 −0
Original line number Diff line number Diff line
@@ -709,6 +709,12 @@ class PowerManagerService extends IPowerManager.Stub
        }

        if (acquireType >= 0) {
            try {
                mActivityService.noteStartWakeLock(acquireUid, acquireName, acquireType);
            } catch (RemoteException e) {
                // Ignore
            }

            try {
                mBatteryStats.noteStartWakelock(acquireUid, acquireName, acquireType);
            } catch (RemoteException e) {
@@ -778,6 +784,12 @@ class PowerManagerService extends IPowerManager.Stub
        releaseType = wl.monitorType;

        if (releaseType >= 0) {
            try {
                mActivityService.noteStopWakeLock(releaseUid, releaseName, releaseType);
            } catch (RemoteException e) {
                // Ignore
            }

            long origId = Binder.clearCallingIdentity();
            try {
                mBatteryStats.noteStopWakelock(releaseUid, releaseName, releaseType);
+43 −0
Original line number Diff line number Diff line
@@ -684,6 +684,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
    final ArrayList<ServiceRecord> mStoppingServices
            = new ArrayList<ServiceRecord>();
    /**
     * Count of WakeLocks held per uid
     */
    final HashMap<Integer, Integer> mUidWakeLocks = new HashMap<Integer, Integer>();
    /**
     * Backup/restore process management
     */
@@ -4253,6 +4258,39 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        }
    }
    public void noteStartWakeLock(int uid, String tag, int type) {
        Integer iuid = Integer.valueOf(uid);
        synchronized (this) {
            Integer count = mUidWakeLocks.get(iuid);
            if (count == null) {
                count = new Integer(1);
                mUidWakeLocks.put(iuid, count);
                updateOomAdjLocked();
            } else {
                ++count;
                mUidWakeLocks.put(iuid, count);
            }
        }
    }
    public void noteStopWakeLock(int uid, String tag, int type) {
        Integer iuid = Integer.valueOf(uid);
        synchronized (this) {
            Integer count = mUidWakeLocks.get(iuid);
            if (count != null) {
                if (--count > 0) {
                    mUidWakeLocks.put(iuid, count);
                } else {
                    mUidWakeLocks.remove(iuid);
                    updateOomAdjLocked();
                }
            } else {
                Log.e(TAG, "Stopping stopped wake lock for uid "
                    + uid + ": " + tag);
            }
        }
    }
    
    /**
     * Perform clean-up of service connections in an activity record.
     */
@@ -13146,6 +13184,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            // counts as being in the foreground.
            adj = FOREGROUND_APP_ADJ;
            app.adjType = "exec-service";
        } else if (mUidWakeLocks.get(app.info.uid) != null) {
            // An app that is currently holding a wakelock also
            // counts as being in the foreground.
            adj = FOREGROUND_APP_ADJ;
            app.adjType = "wakelock";
        } else if (app.foregroundServices) {
            // The user is aware of this app, so make it visible.
            adj = VISIBLE_APP_ADJ;