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

Commit ac31b1a0 authored by Susheel Yadagiri's avatar Susheel Yadagiri Committed by Steve Kondik
Browse files

Bringup 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: I6f23cc17e29e7ce12a138c747765e6bab8c126d9
parent a65e161e
Loading
Loading
Loading
Loading
+96 −16
Original line number Diff line number Diff line
/*
 * Copyright (C) 2006 The Android Open Source Project
 * Copyright (c) 2012-2013, 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.
@@ -27,6 +28,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ApplicationInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -101,6 +103,9 @@ class AlarmManagerService extends IAlarmManager.Stub {

    private Object mLock = new Object();

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

    private int mDescriptor;
    private long mNextWakeup;
    private long mNextRtcWakeup;
@@ -771,6 +776,51 @@ class AlarmManagerService extends IAlarmManager.Stub {
        }
    }

    /* 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) {
                for( int i=0; i< mTriggeredUids.size(); i++) {
                    if(mTriggeredUids.contains(new Integer(uid))) {
                        if (localLOGV) {
                            Slog.v(TAG,"TriggeredUids has this uid, mBroadcastRefCount="
                                +mBroadcastRefCount);
                        }
                        mTriggeredUids.remove(new Integer(uid));
                        mBlockedUids.add(new Integer(uid));
                        if(mBroadcastRefCount > 0){
                            mBroadcastRefCount--;
                            if (mBroadcastRefCount == 0) {
                                /* all the uids for which the alarms are triggered
                                 * are either blocked or have called onSendFinished.
                                */
                                mWakeLock.release();
                                if (localLOGV) Slog.v(TAG, "AM WakeLock Released Internally");
                            }
                        } else {
                            if (localLOGV) {
                                Slog.v(TAG, "Trying to decrement mBroadcastRefCount past zero");
                            }
                        }
                    } else {
                        //no more matching uids break from the for loop
                        break;
                    }
                }
            } else {
                for(int i =0; i<mBlockedUids.size(); i++) {
                    if(!mBlockedUids.remove(new Integer(uid))) {
                        //no more matching uids break from the for loop
                        break;
                     }
                }
            }
        }
    }

    public void removeLocked(PendingIntent operation) {
        boolean didRemove = false;
        for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
@@ -1148,6 +1198,8 @@ class AlarmManagerService extends IAlarmManager.Stub {
        public long repeatInterval;
        public PendingIntent operation;
        public WorkSource workSource;
        public int uid;
        public int pid;
       
        public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen,
                long _interval, PendingIntent _op, WorkSource _ws) {
@@ -1159,6 +1211,8 @@ class AlarmManagerService extends IAlarmManager.Stub {
            repeatInterval = _interval;
            operation = _op;
            workSource = _ws;
            uid = Binder.getCallingUid();
            pid = Binder.getCallingPid();
        }

        @Override
@@ -1279,7 +1333,7 @@ class AlarmManagerService extends IAlarmManager.Stub {
                                    alarm.operation, alarm.workSource);
                            mInFlight.add(inflight);
                            mBroadcastRefCount++;

                            mTriggeredUids.add(new Integer(alarm.uid));
                            final BroadcastStats bs = inflight.mBroadcastStats;
                            bs.count++;
                            if (bs.nesting == 0) {
@@ -1337,11 +1391,10 @@ class AlarmManagerService extends IAlarmManager.Stub {
                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 {
@@ -1530,6 +1583,22 @@ class AlarmManagerService extends IAlarmManager.Stub {
                } else {
                    mLog.w("No in-flight alarm for " + pi + " " + intent);
                }
                String pkg = null;
                int uid = 0;
                try {
                    pkg = pi.getTargetPackage();
                    final PackageManager pm = mContext.getPackageManager();
                    ApplicationInfo appInfo =
                        pm.getApplicationInfo(pkg, PackageManager.GET_META_DATA);
                    uid = appInfo.uid;
                    mTriggeredUids.remove(new Integer(uid));
                } catch (PackageManager.NameNotFoundException ex) {
                    Slog.w(TAG, "onSendFinished NameNotFoundException Pkg = " + pkg);
                }
                if(mBlockedUids.contains(new Integer(uid))) {
                    mBlockedUids.remove(new Integer(uid));
                } else {
                    if(mBroadcastRefCount > 0){
                        mBroadcastRefCount--;
                        if (mBroadcastRefCount == 0) {
                            mWakeLock.release();
@@ -1541,15 +1610,26 @@ class AlarmManagerService extends IAlarmManager.Stub {
                                }
                                mInFlight.clear();
                            }
                        }
                    } else {
                        if(localLOGV) {
                            Slog.e(TAG,"Trying to decrement mBroadcastRefCnt past zero");
                        }
                    }
                }
                if (mBroadcastRefCount != 0) {
                    // the next of our alarms is now in flight.  reattribute the wakelock.
                    if (mInFlight.size() > 0) {
                        InFlight inFlight = mInFlight.get(0);
                        setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource);
                    } else {
                        // should never happen
                        try {
                        mLog.w("Alarm wakelock still held but sent queue empty");
                        mWakeLock.setWorkSource(null);
                        } catch (IllegalArgumentException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
+19 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.AlarmManagerService;
import com.android.internal.util.XmlUtils;
import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.DataConnectionStats;
@@ -123,6 +124,7 @@ import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.android.server.net.BaseNetworkObserver;
import com.android.server.net.LockdownVpnTracker;
import com.android.server.power.PowerManagerService;
import com.google.android.collect.Lists;
import com.google.android.collect.Sets;

@@ -3922,6 +3924,23 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        return ConnectivityManager.TYPE_NONE;
    }

    protected void updateBlockedUids(int uid, boolean isBlocked) {
        try {
            AlarmManagerService mAlarmMgrSvc =
                (AlarmManagerService)ServiceManager.getService(Context.ALARM_SERVICE);
            mAlarmMgrSvc.updateBlockedUids(uid,isBlocked);
        } catch (NullPointerException e) {
            Slog.w(TAG, "Could Not Update blocked Uids with alarmManager" + e);
        }
        try {
            PowerManagerService mPowerMgrSvc =
                (PowerManagerService)ServiceManager.getService(Context.POWER_SERVICE);
            mPowerMgrSvc.updateBlockedUids(uid,isBlocked);
        } catch (NullPointerException e) {
            Slog.w(TAG, "Could Not Update blocked Uids with powerManager" + e);
        }
    }

    /**
     * Have mobile data fail fast if enabled.
     *
+59 −1
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 The Android Open Source Project
 * Copyright (c) 2012-2013, 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.
@@ -394,6 +395,9 @@ public final class PowerManagerService extends IPowerManager.Stub
    // Time when we last logged a warning about calling userActivity() without permission.
    private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;

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

    private native void nativeInit();

    private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
@@ -695,6 +699,15 @@ public final class PowerManagerService extends IPowerManager.Stub
    private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
            WorkSource ws, 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)
@@ -864,12 +877,18 @@ public final class PowerManagerService extends IPowerManager.Stub
    private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {
        synchronized (mLock) {
            int index = findWakeLockIndexLocked(lock);
            int value = SystemProperties.getInt("persist.cne.feature", 0);
            boolean isNsrmEnabled = (value == 4 || value == 5 || value == 6);
            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");
                } else {
                    return;
                }
            }

            WakeLock wakeLock = mWakeLocks.get(index);
@@ -886,6 +905,45 @@ public final class PowerManagerService extends IPowerManager.Stub
        }
    }

    /* 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 (WakeLock wl : mWakeLocks) {
                    if(wl != null) {
                        // release the wakelock for the blocked uid
                        if (wl.mOwnerUid == uid || checkWorkSourceObjectId(uid, wl)) {
                            releaseWakeLockInternal(wl.mLock, wl.mFlags);
                            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++) {