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

Commit ebe51fc0 authored by David Christie's avatar David Christie
Browse files

Add WorkSource capability to AlarmManager.

Change-Id: I663ea3078d405f0fa667a04bdaa376ae6652e994
parent 8c80a476
Loading
Loading
Loading
Loading
+16 −7
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.os.Build;
import android.os.Build;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.WorkSource;


/**
/**
 * This class provides access to the system alarm services.  These allow you
 * This class provides access to the system alarm services.  These allow you
@@ -155,7 +156,7 @@ public class AlarmManager
     * @see #RTC_WAKEUP
     * @see #RTC_WAKEUP
     */
     */
    public void set(int type, long triggerAtMillis, PendingIntent operation) {
    public void set(int type, long triggerAtMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, legacyExactLength(), 0, operation);
        setImpl(type, triggerAtMillis, legacyExactLength(), 0, operation, null);
    }
    }


    /**
    /**
@@ -209,7 +210,7 @@ public class AlarmManager
     */
     */
    public void setRepeating(int type, long triggerAtMillis,
    public void setRepeating(int type, long triggerAtMillis,
            long intervalMillis, PendingIntent operation) {
            long intervalMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, operation);
        setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, operation, null);
    }
    }


    /**
    /**
@@ -244,7 +245,7 @@ public class AlarmManager
     */
     */
    public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
    public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
            PendingIntent operation) {
            PendingIntent operation) {
        setImpl(type, windowStartMillis, windowLengthMillis, 0, operation);
        setImpl(type, windowStartMillis, windowLengthMillis, 0, operation, null);
    }
    }


    /**
    /**
@@ -252,11 +253,17 @@ public class AlarmManager
     * to the precise time specified.
     * to the precise time specified.
     */
     */
    public void setExact(int type, long triggerAtMillis, PendingIntent operation) {
    public void setExact(int type, long triggerAtMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, operation);
        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, operation, null);
    }

    /** @hide */
    public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
            PendingIntent operation, WorkSource workSource) {
        setImpl(type, triggerAtMillis, windowMillis, intervalMillis, operation, workSource);
    }
    }


    private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
    private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
            PendingIntent operation) {
            PendingIntent operation, WorkSource workSource) {
        if (triggerAtMillis < 0) {
        if (triggerAtMillis < 0) {
            /* NOTYET
            /* NOTYET
            if (mAlwaysExact) {
            if (mAlwaysExact) {
@@ -267,8 +274,10 @@ public class AlarmManager
            */
            */
            triggerAtMillis = 0;
            triggerAtMillis = 0;
        }
        }

        try {
        try {
            mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation);
            mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation,
                    workSource);
        } catch (RemoteException ex) {
        } catch (RemoteException ex) {
        }
        }
    }
    }
@@ -361,7 +370,7 @@ public class AlarmManager
    @Deprecated
    @Deprecated
    public void setInexactRepeating(int type, long triggerAtMillis,
    public void setInexactRepeating(int type, long triggerAtMillis,
            long intervalMillis, PendingIntent operation) {
            long intervalMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, operation);
        setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, operation, null);
    }
    }
    
    
    /**
    /**
+2 −1
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package android.app;
package android.app;


import android.app.PendingIntent;
import android.app.PendingIntent;
import android.os.WorkSource;


/**
/**
 * System private API for talking with the alarm manager service.
 * System private API for talking with the alarm manager service.
@@ -26,7 +27,7 @@ import android.app.PendingIntent;
interface IAlarmManager {
interface IAlarmManager {
	/** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */
	/** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */
    void set(int type, long triggerAtTime, long windowLength,
    void set(int type, long triggerAtTime, long windowLength,
            long interval, in PendingIntent operation);
            long interval, in PendingIntent operation, in WorkSource workSource);
    void setTime(long millis);
    void setTime(long millis);
    void setTimeZone(String zone);
    void setTimeZone(String zone);
    void remove(in PendingIntent operation);
    void remove(in PendingIntent operation);
+42 −17
Original line number Original line Diff line number Diff line
@@ -389,19 +389,21 @@ class AlarmManagerService extends IAlarmManager.Stub {
                        ? whenElapsed
                        ? whenElapsed
                                : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval);
                                : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval);
                setImplLocked(a.type, a.when, whenElapsed, maxElapsed,
                setImplLocked(a.type, a.when, whenElapsed, maxElapsed,
                        a.repeatInterval, a.operation, batch.standalone, doValidate);
                        a.repeatInterval, a.operation, batch.standalone, doValidate, a.workSource);
            }
            }
        }
        }
    }
    }


    private static final class InFlight extends Intent {
    private static final class InFlight extends Intent {
        final PendingIntent mPendingIntent;
        final PendingIntent mPendingIntent;
        final WorkSource mWorkSource;
        final Pair<String, ComponentName> mTarget;
        final Pair<String, ComponentName> mTarget;
        final BroadcastStats mBroadcastStats;
        final BroadcastStats mBroadcastStats;
        final FilterStats mFilterStats;
        final FilterStats mFilterStats;


        InFlight(AlarmManagerService service, PendingIntent pendingIntent) {
        InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource) {
            mPendingIntent = pendingIntent;
            mPendingIntent = pendingIntent;
            mWorkSource = workSource;
            Intent intent = pendingIntent.getIntent();
            Intent intent = pendingIntent.getIntent();
            mTarget = intent != null
            mTarget = intent != null
                    ? new Pair<String, ComponentName>(intent.getAction(), intent.getComponent())
                    ? new Pair<String, ComponentName>(intent.getAction(), intent.getComponent())
@@ -498,12 +500,18 @@ class AlarmManagerService extends IAlarmManager.Stub {


    @Override
    @Override
    public void set(int type, long triggerAtTime, long windowLength, long interval,
    public void set(int type, long triggerAtTime, long windowLength, long interval,
            PendingIntent operation) {
            PendingIntent operation, WorkSource workSource) {
        set(type, triggerAtTime, windowLength, interval, operation, false);
        if (workSource != null) {
            mContext.enforceCallingPermission(
                    android.Manifest.permission.UPDATE_DEVICE_STATS,
                    "AlarmManager.set");
        }

        set(type, triggerAtTime, windowLength, interval, operation, false, workSource);
    }
    }


    public void set(int type, long triggerAtTime, long windowLength, long interval,
    public void set(int type, long triggerAtTime, long windowLength, long interval,
            PendingIntent operation, boolean isStandalone) {
            PendingIntent operation, boolean isStandalone, WorkSource workSource) {
        if (operation == null) {
        if (operation == null) {
            Slog.w(TAG, "set/setRepeating ignored because there is no intent");
            Slog.w(TAG, "set/setRepeating ignored because there is no intent");
            return;
            return;
@@ -548,13 +556,14 @@ class AlarmManagerService extends IAlarmManager.Stub {
                        + " interval=" + interval + " standalone=" + isStandalone);
                        + " interval=" + interval + " standalone=" + isStandalone);
            }
            }
            setImplLocked(type, triggerAtTime, triggerElapsed, maxElapsed,
            setImplLocked(type, triggerAtTime, triggerElapsed, maxElapsed,
                    interval, operation, isStandalone, true);
                    interval, operation, isStandalone, true, workSource);
        }
        }
    }
    }


    private void setImplLocked(int type, long when, long whenElapsed, long maxWhen, long interval,
    private void setImplLocked(int type, long when, long whenElapsed, long maxWhen, long interval,
            PendingIntent operation, boolean isStandalone, boolean doValidate) {
            PendingIntent operation, boolean isStandalone, boolean doValidate,
        Alarm a = new Alarm(type, when, whenElapsed, maxWhen, interval, operation);
            WorkSource workSource) {
        Alarm a = new Alarm(type, when, whenElapsed, maxWhen, interval, operation, workSource);
        removeLocked(operation);
        removeLocked(operation);


        boolean reschedule;
        boolean reschedule;
@@ -1039,7 +1048,8 @@ class AlarmManagerService extends IAlarmManager.Stub {
                    final long nextElapsed = alarm.whenElapsed + delta;
                    final long nextElapsed = alarm.whenElapsed + delta;
                    setImplLocked(alarm.type, alarm.when + delta, nextElapsed,
                    setImplLocked(alarm.type, alarm.when + delta, nextElapsed,
                            maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
                            maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
                            alarm.repeatInterval, alarm.operation, batch.standalone, true);
                            alarm.repeatInterval, alarm.operation, batch.standalone, true,
                            alarm.workSource);
                }
                }


            }
            }
@@ -1071,15 +1081,17 @@ class AlarmManagerService extends IAlarmManager.Stub {
        public long maxWhen;        // also in the elapsed time base
        public long maxWhen;        // also in the elapsed time base
        public long repeatInterval;
        public long repeatInterval;
        public PendingIntent operation;
        public PendingIntent operation;
        public WorkSource workSource;
        
        
        public Alarm(int _type, long _when, long _whenElapsed, long _maxWhen,
        public Alarm(int _type, long _when, long _whenElapsed, long _maxWhen,
                long _interval, PendingIntent _op) {
                long _interval, PendingIntent _op, WorkSource _ws) {
            type = _type;
            type = _type;
            when = _when;
            when = _when;
            whenElapsed = _whenElapsed;
            whenElapsed = _whenElapsed;
            maxWhen = _maxWhen;
            maxWhen = _maxWhen;
            repeatInterval = _interval;
            repeatInterval = _interval;
            operation = _op;
            operation = _op;
            workSource = _ws;
        }
        }


        @Override
        @Override
@@ -1193,11 +1205,11 @@ class AlarmManagerService extends IAlarmManager.Stub {
                            
                            
                            // we have an active broadcast so stay awake.
                            // we have an active broadcast so stay awake.
                            if (mBroadcastRefCount == 0) {
                            if (mBroadcastRefCount == 0) {
                                setWakelockWorkSource(alarm.operation);
                                setWakelockWorkSource(alarm.operation, alarm.workSource);
                                mWakeLock.acquire();
                                mWakeLock.acquire();
                            }
                            }
                            final InFlight inflight = new InFlight(AlarmManagerService.this,
                            final InFlight inflight = new InFlight(AlarmManagerService.this,
                                    alarm.operation);
                                    alarm.operation, alarm.workSource);
                            mInFlight.add(inflight);
                            mInFlight.add(inflight);
                            mBroadcastRefCount++;
                            mBroadcastRefCount++;


@@ -1239,8 +1251,18 @@ class AlarmManagerService extends IAlarmManager.Stub {
        }
        }
    }
    }


    void setWakelockWorkSource(PendingIntent pi) {
    /**
     * Attribute blame for a WakeLock.
     * @param pi PendingIntent to attribute blame to if ws is null.
     * @param ws WorkSource to attribute blame.
     */
    void setWakelockWorkSource(PendingIntent pi, WorkSource ws) {
        try {
        try {
            if (ws != null) {
                mWakeLock.setWorkSource(ws);
                return;
            }

            final int uid = ActivityManagerNative.getDefault()
            final int uid = ActivityManagerNative.getDefault()
                    .getUidForIntentSender(pi.getTarget());
                    .getUidForIntentSender(pi.getTarget());
            if (uid >= 0) {
            if (uid >= 0) {
@@ -1323,8 +1345,9 @@ class AlarmManagerService extends IAlarmManager.Stub {
            // the top of the next minute.
            // the top of the next minute.
            final long tickEventDelay = nextTime - currentTime;
            final long tickEventDelay = nextTime - currentTime;


            final WorkSource workSource = null; // Let system take blame for time tick events.
            set(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0,
            set(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0,
                    0, mTimeTickSender, true);
                    0, mTimeTickSender, true, workSource);
        }
        }


        public void scheduleDateChangedEvent() {
        public void scheduleDateChangedEvent() {
@@ -1336,7 +1359,8 @@ class AlarmManagerService extends IAlarmManager.Stub {
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.add(Calendar.DAY_OF_MONTH, 1);
            calendar.add(Calendar.DAY_OF_MONTH, 1);


            set(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, true);
            final WorkSource workSource = null; // Let system take blame for date change events.
            set(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, true, workSource);
        }
        }
    }
    }
    
    
@@ -1452,7 +1476,8 @@ class AlarmManagerService extends IAlarmManager.Stub {
                } else {
                } else {
                    // the next of our alarms is now in flight.  reattribute the wakelock.
                    // the next of our alarms is now in flight.  reattribute the wakelock.
                    if (mInFlight.size() > 0) {
                    if (mInFlight.size() > 0) {
                        setWakelockWorkSource(mInFlight.get(0).mPendingIntent);
                        InFlight inFlight = mInFlight.get(0);
                        setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource);
                    } else {
                    } else {
                        // should never happen
                        // should never happen
                        mLog.w("Alarm wakelock still held but sent queue empty");
                        mLog.w("Alarm wakelock still held but sent queue empty");
+2 −1
Original line number Original line Diff line number Diff line
@@ -878,7 +878,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
        mAlarmManager.remove(isA(PendingIntent.class));
        mAlarmManager.remove(isA(PendingIntent.class));
        expectLastCall().anyTimes();
        expectLastCall().anyTimes();


        mAlarmManager.set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), anyLong(), isA(PendingIntent.class));
        mAlarmManager.set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), anyLong(),
                isA(PendingIntent.class), isA(WorkSource.class));
        expectLastCall().atLeastOnce();
        expectLastCall().atLeastOnce();


        mNetManager.setGlobalAlert(anyLong());
        mNetManager.setGlobalAlert(anyLong());