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

Commit 4ea46abf authored by Bhavya Sokke Mallikarjunappa's avatar Bhavya Sokke Mallikarjunappa Committed by Ricardo Cerqueira
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 some power.

Change-Id: Ice992713994045d0582f8cfb7b6761e2689f2555
Conflicts:
services/core/java/com/android/server/AlarmManagerService.java
parent 60c24279
Loading
Loading
Loading
Loading
+68 −7
Original line number Diff line number Diff line
/*
 * Copyright (C) 2006 The Android Open Source Project
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -114,6 +115,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 mNextRtcWakeup;
@@ -560,9 +564,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) {
                int alarmType, String tag, int uid) {
            mPendingIntent = pendingIntent;
            mWorkSource = workSource;
            mTag = tag;
@@ -574,6 +579,7 @@ class AlarmManagerService extends SystemService {
            }
            mFilterStats = fs;
            mAlarmType = alarmType;
            mUid = uid;
        }
    }

@@ -1280,6 +1286,44 @@ class AlarmManagerService extends SystemService {
        }
    }

    /* updates the blocked uids, so if a wake lock is acquired to only fire
     * alarm for it, it can be released.
     */
    void updateBlockedUids(int uid, boolean isBlocked) {
        if (localLOGV) Slog.v(TAG, "UpdateBlockedUids: uid = "+uid +" isBlocked = "+isBlocked);
        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();
            }
        }
    }

    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--) {
@@ -1555,6 +1599,8 @@ class AlarmManagerService extends SystemService {
        public final AlarmManager.AlarmClockInfo alarmClock;
        public final int userId;
        public PriorityClass priorityClass;
        public int uid;
        public int pid;

        public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen,
                long _interval, PendingIntent _op, WorkSource _ws,
@@ -1573,6 +1619,8 @@ class AlarmManagerService extends SystemService {
            workSource = _ws;
            alarmClock = _info;
            userId = _userId;
            uid = Binder.getCallingUid();
            pid = Binder.getCallingPid();
        }

        public static String makeTag(PendingIntent pi, int type) {
@@ -1680,15 +1728,16 @@ class AlarmManagerService extends SystemService {
                        mResultReceiver, mHandler);

                // 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);
                        alarm.operation, alarm.workSource, alarm.type, alarm.tag, alarm.uid);
                mInFlight.add(inflight);
                mBroadcastRefCount++;
                mTriggeredUids.add(new Integer(alarm.uid));

                final BroadcastStats bs = inflight.mBroadcastStats;
                bs.count++;
@@ -1876,11 +1925,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 {
@@ -2113,9 +2161,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;
                    }
@@ -2138,8 +2188,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");
+74 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 The Android Open Source Project
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -157,6 +158,9 @@ public final class PowerManagerService extends SystemService

    private static final int BUTTON_ON_DURATION = 5 * 1000;

    // Config value for NSRM
    private static final int DPM_CONFIG_FEATURE_MASK_NSRM = 0x00000004;

    private final Context mContext;
    private final ServiceThread mHandlerThread;
    private final PowerManagerHandler mHandler;
@@ -428,6 +432,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);
@@ -726,6 +733,15 @@ public final class PowerManagerService extends SystemService
    private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
            WorkSource ws, String historyTag, int uid, int pid) {
        synchronized (mLock) {
            if(mBlockedUids.contains(new Integer(uid)) && uid != Process.myUid()) {
                //wakelock acquisition for blocked uid, do not acquire.
                if (DEBUG_SPEW) {
                    Slog.d(TAG, "uid is blocked not acquiring wakeLock flags=0x" +
                            Integer.toHexString(flags) + " tag=" + tag + " uid=" + uid +
                            " pid =" + pid);
                }
                return;
            }
            if (DEBUG_SPEW) {
                Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
                        + ", flags=0x" + Integer.toHexString(flags)
@@ -852,13 +868,23 @@ public final class PowerManagerService extends SystemService
            int callingUid) {
        synchronized (mLock) {
            int index = findWakeLockIndexLocked(lock);
            int value = SystemProperties.getInt("persist.dpm.feature", 0);
            boolean isNsrmEnabled = false;

            if ((value & DPM_CONFIG_FEATURE_MASK_NSRM) == DPM_CONFIG_FEATURE_MASK_NSRM)
                isNsrmEnabled = true;

            if (index < 0) {
                if (DEBUG_SPEW) {
                    Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
                            + " [not found], ws=" + ws);
                }
                if (!isNsrmEnabled) {
                throw new IllegalArgumentException("Wake lock not active: " + lock
                        + " from uid " + callingUid);
                } else {
                    return;
                }
            }

            WakeLock wakeLock = mWakeLocks.get(index);
@@ -877,6 +903,54 @@ public final class PowerManagerService extends SystemService
        }
    }

    /* updates the blocked uids, so if a wake lock is acquired for it
     * can be released.
     */
    public void updateBlockedUids(int uid, boolean isBlocked) {
        synchronized(mLock) {
            if (DEBUG_SPEW) Slog.v(TAG, "updateBlockedUids: uid = "+uid +"isBlocked = "+isBlocked);
            if(isBlocked) {
                mBlockedUids.add(new Integer(uid));
                for (int index = 0; index < mWakeLocks.size(); index++) {
                    WakeLock wl = mWakeLocks.get(index);
                    if(wl != null) {
                        if(wl.mTag.startsWith("*sync*") && wl.mOwnerUid == Process.SYSTEM_UID) {
                            releaseWakeLockInternal(wl.mLock, wl.mFlags);
                            index--;
                            if (DEBUG_SPEW) Slog.v(TAG, "Internally releasing the wakelock"
                                    + "acquired by SyncManager");
                            continue;
                        }
                        // release the wakelock for the blocked uid
                        if (wl.mOwnerUid == uid || checkWorkSourceObjectId(uid, wl)) {
                            releaseWakeLockInternal(wl.mLock, wl.mFlags);
                            index--;
                            if (DEBUG_SPEW) Slog.v(TAG, "Internally releasing it");
                        }
                    }
                }
            }
            else {
                mBlockedUids.remove(new Integer(uid));
            }
        }
    }

    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;
    }

    private int findWakeLockIndexLocked(IBinder lock) {
        final int count = mWakeLocks.size();
        for (int i = 0; i < count; i++) {
+53 −1
Original line number Diff line number Diff line
/*
 * Copyright (C) 2006 The Android Open Source Project
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -99,6 +100,8 @@ import com.android.server.webkit.WebViewUpdateService;
import com.android.server.wm.WindowManagerService;

import dalvik.system.VMRuntime;
import dalvik.system.PathClassLoader;
import java.lang.reflect.Constructor;

import java.io.File;
import java.util.Timer;
@@ -152,6 +155,7 @@ public final class SystemServer {
    // TODO: remove all of these references by improving dependency resolution and boot phases
    private Installer mInstaller;
    private PowerManagerService mPowerManagerService;
    private AlarmManagerService mAlarmManagerService;
    private ActivityManagerService mActivityManagerService;
    private DisplayManagerService mDisplayManagerService;
    private PackageManagerService mPackageManagerService;
@@ -462,7 +466,7 @@ public final class SystemServer {
            consumerIr = new ConsumerIrService(context);
            ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);

            mSystemServiceManager.startService(AlarmManagerService.class);
            mAlarmManagerService = mSystemServiceManager.startService(AlarmManagerService.class);
            alarm = IAlarmManager.Stub.asInterface(
                    ServiceManager.getService(Context.ALARM_SERVICE));

@@ -695,6 +699,12 @@ public final class SystemServer {
                } catch (Throwable e) {
                    reportWtf("starting Service Discovery Service", e);
                }
                try {
                    Slog.i(TAG, "DPM Service");
                    startDpmService(context, this);
                } catch (Throwable e) {
                    reportWtf("starting DpmService", e);
                }
            }

            if (!disableNonCoreServices) {
@@ -1217,4 +1227,46 @@ public final class SystemServer {
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.OWNER);
    }

    private static final void startDpmService(Context context, SystemServer systemServer) {
        try {
            Object dpmObj = null;
            int dpmFeature = SystemProperties.getInt("persist.dpm.feature", 0);
            Slog.i(TAG, "DPM configuration set to " + dpmFeature);

            if (dpmFeature > 0 && dpmFeature < 8) {
                PathClassLoader dpmClassLoader =
                    new PathClassLoader("/system/framework/com.qti.dpmframework.jar",
                            ClassLoader.getSystemClassLoader());
                Class dpmClass = dpmClassLoader.loadClass("com.qti.dpm.DpmService");
                Constructor dpmConstructor = dpmClass.getConstructor(
                        new Class[] {Context.class, SystemServer.class});
                dpmObj = dpmConstructor.newInstance(context, systemServer);
                try {
                    if(dpmObj != null && (dpmObj instanceof IBinder)) {
                        ServiceManager.addService("dpmservice", (IBinder)dpmObj);
                        Slog.i(TAG, "Created DPM Service");
                    }
                } catch (Exception e) {
                    Slog.i(TAG, "starting DPM Service", e);
                }
            }
        } catch (Throwable e) {
            Slog.i(TAG, "starting DPM Service", e);
        }
    }


    public void updateBlockedUids(int uid, boolean isBlocked) {
        try {
            mAlarmManagerService.updateBlockedUids(uid, isBlocked);
        } catch (NullPointerException e) {
            Slog.w(TAG, "Could Not Update blocked Uids with alarmManager" + e);
        }
        try {
            mPowerManagerService.updateBlockedUids(uid, isBlocked);
        } catch (NullPointerException e) {
            Slog.w(TAG, "Could Not Update blocked Uids with powerManager" + e);
        }
    }
}