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

Commit 6de68dfa authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Fix issue #34471029: Don't allow audio use from background apps."

parents f3d79e4e 3e99f654
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -172,6 +172,9 @@ public class ActivityManager {
        @Override
        public void onUidIdle(int uid, boolean disabled) {
        }

        @Override public void onUidCachedChanged(int uid, boolean cached) {
        }
    }

    final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>();
@@ -563,6 +566,9 @@ public class ActivityManager {
    /** @hide Flag for registerUidObserver: report uid has become active. */
    public static final int UID_OBSERVER_ACTIVE = 1<<3;

    /** @hide Flag for registerUidObserver: report uid cached state has changed. */
    public static final int UID_OBSERVER_CACHED = 1<<4;

    /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: normal free-to-run operation. */
    public static final int APP_START_MODE_NORMAL = 0;

+10 −0
Original line number Diff line number Diff line
@@ -43,4 +43,14 @@ oneway interface IUidObserver {
     * a sufficient period of time, or all of its processes have gone away.
     */
    void onUidIdle(int uid, boolean disabled);

    /**
     * Report when the cached state of a uid has changed.
     * If true, a uid has become cached -- that is, it has some active processes that are
     * all in the cached state.  It should be doing as little as possible at this point.
     * If false, that a uid is no longer cached.  This will only be called after
     * onUidCached() has been reported true.  It will happen when either one of its actively
     * running processes is no longer cached, or it no longer has any actively running processes.
     */
    void onUidCachedChanged(int uid, boolean cached);
}
+0 −11
Original line number Diff line number Diff line
@@ -59,15 +59,4 @@ public abstract class AudioManagerInternal {

        int getRingerModeAffectedStreams(int streams);
    }

    /**
     * Disable or restore the ability to play audio for a given UID.
     * When a UID isn't meant to be tracked anymore (e.g. client died), re-enable audio for this UID
     * to prevent disabling audio for future UIDs that would reuse the same value.
     * This operation is asynchronous.
     * @param disable when true, prevents playback of audio streams from the given uid. If false,
     *         restores the ability to play, or no-op if playback hadn't been disabled before.
     * @param uid the client UID whose ability to play will be affected.
     */
    public abstract void disableAudioForUid(boolean disable, int uid);
}
+7 −5
Original line number Diff line number Diff line
@@ -2893,11 +2893,10 @@ class AlarmManagerService extends SystemService {
    }

    final class UidObserver extends IUidObserver.Stub {
        @Override public void onUidStateChanged(int uid, int procState,
                long procStateSeq) throws RemoteException {
        @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
        }

        @Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
        @Override public void onUidGone(int uid, boolean disabled) {
            if (disabled) {
                synchronized (mLock) {
                    removeForStoppedLocked(uid);
@@ -2905,16 +2904,19 @@ class AlarmManagerService extends SystemService {
            }
        }

        @Override public void onUidActive(int uid) throws RemoteException {
        @Override public void onUidActive(int uid) {
        }

        @Override public void onUidIdle(int uid, boolean disabled) throws RemoteException {
        @Override public void onUidIdle(int uid, boolean disabled) {
            if (disabled) {
                synchronized (mLock) {
                    removeForStoppedLocked(uid);
                }
            }
        }

        @Override public void onUidCachedChanged(int uid, boolean cached) {
        }
    };

    private final BroadcastStats getStatsLocked(PendingIntent pi) {
+73 −28
Original line number Diff line number Diff line
@@ -4344,8 +4344,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
            for (int j = 0; j < N; ++j) {
                final UidRecord.ChangeItem item = mActiveUidChanges[j];
                if (item.change == UidRecord.CHANGE_GONE
                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
                    mValidateUids.remove(item.uid);
                } else {
                    UidRecord validateUid = mValidateUids.get(item.uid);
@@ -4353,9 +4352,9 @@ public class ActivityManagerService extends IActivityManager.Stub
                        validateUid = new UidRecord(item.uid);
                        mValidateUids.put(item.uid, validateUid);
                    }
                    if (item.change == UidRecord.CHANGE_IDLE) {
                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
                        validateUid.idle = true;
                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
                        validateUid.idle = false;
                    }
                    validateUid.curProcState = validateUid.setProcState = item.processState;
@@ -4380,22 +4379,37 @@ public class ActivityManagerService extends IActivityManager.Stub
            for (int j = 0; j < changesSize; j++) {
                UidRecord.ChangeItem item = mActiveUidChanges[j];
                final int change = item.change;
                if (change == UidRecord.CHANGE_IDLE
                        || change == UidRecord.CHANGE_GONE_IDLE) {
                if (change == UidRecord.CHANGE_PROCSTATE &&
                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
                    // No-op common case: no significant change, the observer is not
                    // interested in all proc state changes.
                    continue;
                }
                if ((change & UidRecord.CHANGE_IDLE) != 0) {
                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                "UID idle uid=" + item.uid);
                        observer.onUidIdle(item.uid, item.ephemeral);
                    }
                } else if (change == UidRecord.CHANGE_ACTIVE) {
                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                "UID active uid=" + item.uid);
                        observer.onUidActive(item.uid);
                    }
                }
                if (change == UidRecord.CHANGE_GONE
                        || change == UidRecord.CHANGE_GONE_IDLE) {
                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                "UID cached uid=" + item.uid);
                        observer.onUidCachedChanged(item.uid, true);
                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                "UID active uid=" + item.uid);
                        observer.onUidCachedChanged(item.uid, false);
                    }
                }
                if ((change & UidRecord.CHANGE_GONE) != 0) {
                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                                "UID gone uid=" + item.uid);
@@ -22171,10 +22185,10 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
            if (uidRec != null) {
                uidRec.pendingChange = pendingChange;
                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
                    // If this uid is going away, and we haven't yet reported it is gone,
                    // then do so now.
                    change = UidRecord.CHANGE_GONE_IDLE;
                    change |= UidRecord.CHANGE_IDLE;
                }
            } else if (uid < 0) {
                throw new IllegalArgumentException("No UidRecord or uid");
@@ -22184,8 +22198,26 @@ public class ActivityManagerService extends IActivityManager.Stub
            mPendingUidChanges.add(pendingChange);
        } else {
            pendingChange = uidRec.pendingChange;
            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
                change = UidRecord.CHANGE_GONE_IDLE;
            // If there is no change in idle or active state, then keep whatever was pending.
            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
                        | UidRecord.CHANGE_ACTIVE));
            }
            // If there is no change in cached or uncached state, then keep whatever was pending.
            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
                        | UidRecord.CHANGE_UNCACHED));
            }
            // If this is a report of the UID being gone, then we shouldn't keep any previous
            // report of it being active or cached.  (That is, a gone uid is never active,
            // and never cached.)
            if ((change & UidRecord.CHANGE_GONE) != 0) {
                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
                if (!uidRec.idle) {
                    // If this uid is going away, and we haven't yet reported it is gone,
                    // then do so now.
                    change |= UidRecord.CHANGE_IDLE;
                }
            }
        }
        pendingChange.change = change;
@@ -22194,27 +22226,26 @@ public class ActivityManagerService extends IActivityManager.Stub
        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
        if (uidRec != null) {
            uidRec.lastReportedChange = change;
            uidRec.updateLastDispatchedProcStateSeq(change);
        }
        // Directly update the power manager, since we sit on top of it and it is critical
        // it be kept in sync (so wake locks will be held as soon as appropriate).
        if (mLocalPowerManager != null) {
            switch (change) {
                case UidRecord.CHANGE_GONE:
                case UidRecord.CHANGE_GONE_IDLE:
                    mLocalPowerManager.uidGone(pendingChange.uid);
                    break;
                case UidRecord.CHANGE_IDLE:
                    mLocalPowerManager.uidIdle(pendingChange.uid);
                    break;
                case UidRecord.CHANGE_ACTIVE:
            // TO DO: dispatch cached/uncached changes here, so we don't need to report
            // all proc state changes.
            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
                mLocalPowerManager.uidActive(pendingChange.uid);
                    break;
                default:
            }
            if ((change & UidRecord.CHANGE_IDLE) != 0) {
                mLocalPowerManager.uidIdle(pendingChange.uid);
            }
            if ((change & UidRecord.CHANGE_GONE) != 0) {
                mLocalPowerManager.uidGone(pendingChange.uid);
            } else {
                mLocalPowerManager.updateUidProcState(pendingChange.uid,
                        pendingChange.processState);
                    break;
            }
        }
    }
@@ -22798,6 +22829,9 @@ public class ActivityManagerService extends IActivityManager.Stub
                                    mConstants.BACKGROUND_SETTLE_TIME);
                        }
                    }
                    if (!uidRec.setIdle) {
                        uidChange = UidRecord.CHANGE_IDLE;
                    }
                } else {
                    if (uidRec.idle) {
                        uidChange = UidRecord.CHANGE_ACTIVE;
@@ -22806,8 +22840,17 @@ public class ActivityManagerService extends IActivityManager.Stub
                    }
                    uidRec.lastBackgroundTime = 0;
                }
                final boolean wasCached = uidRec.setProcState
                        > ActivityManager.PROCESS_STATE_RECEIVER && uidRec.setProcState
                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
                final boolean isCached = uidRec.curProcState
                        > ActivityManager.PROCESS_STATE_RECEIVER;
                if (wasCached != isCached) {
                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
                }
                uidRec.setProcState = uidRec.curProcState;
                uidRec.setWhitelist = uidRec.curWhitelist;
                uidRec.setIdle = uidRec.idle;
                enqueueUidChangeLocked(uidRec, -1, uidChange);
                noteUidProcessState(uidRec.uid, uidRec.curProcState);
                if (uidRec.foregroundServices) {
@@ -22882,6 +22925,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                                    userId == UserHandle.getUserId(uidRec.uid)) {
                                EventLogTags.writeAmUidIdle(uidRec.uid);
                                uidRec.idle = true;
                                uidRec.setIdle = true;
                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
                                        + " from package " + packageName + " user " + userId);
                                doStopUidLocked(uidRec.uid, uidRec);
@@ -22917,6 +22961,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    if (bgTime <= maxBgTime) {
                        EventLogTags.writeAmUidIdle(uidRec.uid);
                        uidRec.idle = true;
                        uidRec.setIdle = true;
                        doStopUidLocked(uidRec.uid, uidRec);
                    } else {
                        if (nextTime == 0 || nextTime > bgTime) {
Loading