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

Commit 6837e455 authored by Susheel Yadagiri's avatar Susheel Yadagiri Committed by Linux Build Service Account
Browse files

Enable NSRM (Network Socket Request Manager).

NSRM is a feature to synchronize app socket requests
to reduce network signalling and there by save power.

Change-Id: Ic34b9c54404ba2156701da1f63232013978bf3a4
parent f2e4499a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ interface IAlarmManager {
    void remove(in PendingIntent operation);
    long getNextWakeFromIdleTime();
    AlarmManager.AlarmClockInfo getNextAlarmClock(int userId);
    // update the uids being synchronized by network socket request manager
    void updateBlockedUids(int uid, boolean isBlocked);
}

+2 −0
Original line number Diff line number Diff line
@@ -60,4 +60,6 @@ interface IPowerManager

    // sets the attention light (used by phone app only)
    void setAttentionLight(boolean on, int color);
    // update the uids being synchronized by network socket request manager
    void updateBlockedUids(int uid, boolean isBlocked);
}
+77 −7
Original line number Diff line number Diff line
@@ -111,6 +111,9 @@ class AlarmManagerService extends SystemService {

    final Object mLock = new Object();

    private final ArrayList<Integer> mTriggeredUids = new ArrayList<Integer>();
    private final ArrayList<Integer> mBlockedUids = new ArrayList<Integer>();

    long mNativeData;
    private long mNextWakeup;
    private long mNextNonWakeup;
@@ -732,9 +735,10 @@ class AlarmManagerService extends SystemService {
        final BroadcastStats mBroadcastStats;
        final FilterStats mFilterStats;
        final int mAlarmType;
        final int mUid;

        InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource,
                int alarmType, String tag, long nowELAPSED) {
                int alarmType, String tag, long nowELAPSED, int uid) {
            mPendingIntent = pendingIntent;
            mWorkSource = workSource;
            mTag = tag;
@@ -747,6 +751,7 @@ class AlarmManagerService extends SystemService {
            fs.lastTime = nowELAPSED;
            mFilterStats = fs;
            mAlarmType = alarmType;
            mUid = uid;
        }
    }

@@ -1174,6 +1179,39 @@ class AlarmManagerService extends SystemService {

            dumpImpl(pw);
        }

        @Override
        /* updates the blocked uids, so if a wake lock is acquired to only fire
         * alarm for it, it can be released.
         */
        public void updateBlockedUids(int uid, boolean isBlocked) {

            if (localLOGV) Slog.v(TAG, "UpdateBlockedUids: uid = " + uid +
                                  " isBlocked = " + isBlocked);

            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
                if (localLOGV) Slog.v(TAG, "UpdateBlockedUids is not allowed");
                return;
            }

            synchronized(mLock) {
                if(isBlocked) {
                    mBlockedUids.add(new Integer(uid));
                    if (checkReleaseWakeLock()) {
                        /* all the uids for which the alarms are triggered
                         * are either blocked or have called onSendFinished.
                         */
                        if (mWakeLock.isHeld()) {
                            mWakeLock.release();
                            if (localLOGV)
                                Slog.v(TAG, "AM WakeLock Released Internally in updateBlockedUids");
                        }
                    }
                } else {
                    mBlockedUids.clear();
                }
            }
        }
    };

    void dumpImpl(PrintWriter pw) {
@@ -1630,6 +1668,20 @@ class AlarmManagerService extends SystemService {
        }
    }

    boolean checkReleaseWakeLock() {
        if (mTriggeredUids.size() == 0 || mBlockedUids.size() == 0)
            return false;

        int uid;
        for (int i = 0; i <  mTriggeredUids.size(); i++) {
            uid = mTriggeredUids.get(i);
            if (!mBlockedUids.contains(uid)) {
                return false;
            }
        }
        return true;
    }

    private void removeLocked(PendingIntent operation) {
        boolean didRemove = false;
        for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
@@ -1959,6 +2011,7 @@ class AlarmManagerService extends SystemService {
        public long maxWhenElapsed; // also in the elapsed time base
        public long repeatInterval;
        public PriorityClass priorityClass;
        public int pid;

        public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen,
                long _interval, PendingIntent _op, WorkSource _ws, int _flags,
@@ -1978,6 +2031,7 @@ class AlarmManagerService extends SystemService {
            flags = _flags;
            alarmClock = _info;
            uid = _uid;
            pid = Binder.getCallingPid();
        }

        public static String makeTag(PendingIntent pi, int type) {
@@ -2117,15 +2171,19 @@ class AlarmManagerService extends SystemService {
                        mResultReceiver, mHandler, null, allowWhileIdle ? mIdleOptions : null);

                // we have an active broadcast so stay awake.
                if (mBroadcastRefCount == 0) {
                if (mBroadcastRefCount == 0 || !mWakeLock.isHeld()) {
                    setWakelockWorkSource(alarm.operation, alarm.workSource,
                            alarm.type, alarm.tag, true);
                    mWakeLock.acquire();
                }
                final InFlight inflight = new InFlight(AlarmManagerService.this,
                        alarm.operation, alarm.workSource, alarm.type, alarm.tag, nowELAPSED);
                                                       alarm.operation,
                                                       alarm.workSource,
                                                       alarm.type, alarm.tag,
                                                       nowELAPSED, alarm.uid);
                mInFlight.add(inflight);
                mBroadcastRefCount++;
                mTriggeredUids.add(new Integer(alarm.uid));

                if (allowWhileIdle) {
                    // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm.
@@ -2321,11 +2379,10 @@ class AlarmManagerService extends SystemService {
                mWakeLock.setWorkSource(new WorkSource(uid));
                return;
            }
        } catch (Exception e) {
        }

            // Something went wrong; fall back to attributing the lock to the OS
            mWakeLock.setWorkSource(null);
        } catch (Exception e) {
        }
    }

    private class AlarmHandler extends Handler {
@@ -2533,9 +2590,11 @@ class AlarmManagerService extends SystemService {
        public void onSendFinished(PendingIntent pi, Intent intent, int resultCode,
                String resultData, Bundle resultExtras) {
            synchronized (mLock) {
                int uid = 0;
                InFlight inflight = null;
                for (int i=0; i<mInFlight.size(); i++) {
                    if (mInFlight.get(i).mPendingIntent == pi) {
                        uid = mInFlight.get(i).mUid;
                        inflight = mInFlight.remove(i);
                        break;
                    }
@@ -2569,8 +2628,19 @@ class AlarmManagerService extends SystemService {
                    mLog.w("No in-flight alarm for " + pi + " " + intent);
                }
                mBroadcastRefCount--;
                mTriggeredUids.remove(new Integer(uid));

                if (checkReleaseWakeLock()) {
                    if (mWakeLock.isHeld()) {
                        mWakeLock.release();
                        if (localLOGV) Slog.v(TAG, "AM WakeLock Released Internally onSendFinish");
                    }
                }

                if (mBroadcastRefCount == 0) {
                    if (mWakeLock.isHeld()) {
                      mWakeLock.release();
                    }
                    if (mInFlight.size() > 0) {
                        mLog.w("Finished all broadcasts with " + mInFlight.size()
                                + " remaining inflights");
+81 −0
Original line number Diff line number Diff line
@@ -453,6 +453,9 @@ public final class PowerManagerService extends SystemService
    private final ArrayList<PowerManagerInternal.LowPowerModeListener> mLowPowerModeListeners
            = new ArrayList<PowerManagerInternal.LowPowerModeListener>();

    //track the blocked uids.
    private final ArrayList<Integer> mBlockedUids = new ArrayList<Integer>();

    private native void nativeInit();

    private static native void nativeAcquireSuspendBlocker(String name);
@@ -800,6 +803,15 @@ public final class PowerManagerService extends SystemService
                }
                mWakeLocks.add(wakeLock);
                setWakeLockDisabledStateLocked(wakeLock);
                if(mBlockedUids.contains(new Integer(uid)) && uid != Process.myUid()) {
                    //wakelock acquisition for blocked uid, disable it.
                    if (DEBUG_SPEW) {
                        Slog.d(TAG, "uid is blocked disabling wakeLock flags=0x" +
                                Integer.toHexString(flags) + " tag=" + tag + " uid=" + uid +
                                " pid =" + pid);
                    }
                    updateBlockedWakelock(wakeLock, true);
                }
                notifyAcquire = true;
            }

@@ -3448,6 +3460,43 @@ public final class PowerManagerService extends SystemService
                Binder.restoreCallingIdentity(ident);
            }
        }

        /* updates the blocked uids, so if a wake lock is acquired for it
         * can be released.
         */
        public void updateBlockedUids(int uid, boolean isBlocked) {
            boolean changed = false;
            if (DEBUG_SPEW) Slog.v(TAG, "updateBlockedUids: uid = " + uid +
                                   "isBlocked = " + isBlocked);
            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
                if (DEBUG_SPEW) Slog.v(TAG, "UpdateBlockedUids is not allowed");
                return;
            }
            synchronized(mLock) {
                for (int index = 0; index < mWakeLocks.size(); index++) {
                    WakeLock wl = mWakeLocks.get(index);
                    if(wl != null) {
                        // update the wakelock for the blocked uid
                        if ((wl.mOwnerUid == uid || checkWorkSourceObjectId(uid, wl)) ||
                            (wl.mTag.startsWith("*sync*") && wl.mOwnerUid == Process.SYSTEM_UID)) {
                            if(updateBlockedWakelock(wl, isBlocked)){
                                changed = true;
                            }
                        }
                    }
                }
                if(isBlocked) {
                    mBlockedUids.add(new Integer(uid));
                }
                else {
                    mBlockedUids.clear();
                }
            }
            if(changed){
                mDirty |= DIRTY_WAKE_LOCKS;
                updatePowerStateLocked();
            }
        }
    }

    private final class LocalService extends PowerManagerInternal {
@@ -3535,4 +3584,36 @@ public final class PowerManagerService extends SystemService
            uidGoneInternal(uid);
        }
    }

    private boolean updateBlockedWakelock(WakeLock wakeLock, boolean update) {
        if (wakeLock != null && ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
                == PowerManager.PARTIAL_WAKE_LOCK )) {
            if(wakeLock.mDisabled != update){
                wakeLock.mDisabled = update;
                if (wakeLock.mDisabled) {
                    // This wake lock is no longer being respected.
                    notifyWakeLockReleasedLocked(wakeLock);
                } else {
                    notifyWakeLockAcquiredLocked(wakeLock);
                }
                return true;
            }
        }
        return false;
    }

    private boolean checkWorkSourceObjectId(int uid, WakeLock wl) {
        try {
            for (int index = 0; index < wl.mWorkSource.size(); index++) {
                if (uid == wl.mWorkSource.get(index)) {
                    if (DEBUG_SPEW) Slog.v(TAG, "WS uid matched");
                    return true;
                }
            }
        }
        catch (Exception e) {
            return false;
        }
        return false;
    }
}