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

Commit c2ce0ac9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove cancel listeners from pending intent alarms" into qt-qpr1-dev

parents 78ee3320 c8e11628
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1257,7 +1257,12 @@ public final class PendingIntent implements Parcelable {
        return b != null ? new PendingIntent(b, in.getClassCookie(PendingIntent.class)) : null;
    }

    /*package*/ PendingIntent(IIntentSender target) {
    /**
     * Creates a PendingIntent with the given target.
     * @param target the backing IIntentSender
     * @hide
     */
    public PendingIntent(IIntentSender target) {
        mTarget = target;
    }

+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server;

import android.app.PendingIntent;

public interface AlarmManagerInternal {
    // Some other components in the system server need to know about
    // broadcast alarms currently in flight
@@ -30,4 +32,10 @@ public interface AlarmManagerInternal {
    boolean isIdling();
    public void removeAlarmsForUid(int uid);
    public void registerInFlightListener(InFlightListener callback);

    /**
     * Removes any alarm with the given pending intent with equality determined using
     * {@link android.app.PendingIntent#equals(java.lang.Object) PendingIntent.equals}
     */
    void remove(PendingIntent rec);
}
+10 −21
Original line number Diff line number Diff line
@@ -210,7 +210,6 @@ class AlarmManagerService extends SystemService {
    IAlarmListener mTimeTickTrigger;
    PendingIntent mDateChangeSender;
    Random mRandom;
    PendingIntent.CancelListener mOperationCancelListener;
    boolean mInteractive = true;
    long mNonInteractiveStartTime;
    long mNonInteractiveTime;
@@ -1498,7 +1497,6 @@ class AlarmManagerService extends SystemService {

        synchronized (mLock) {
            mHandler = new AlarmHandler();
            mOperationCancelListener = (intent) -> removeImpl(intent, null);
            mConstants = new Constants(mHandler);
            mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);

@@ -1750,9 +1748,6 @@ class AlarmManagerService extends SystemService {
        } else {
            maxElapsed = triggerElapsed + windowLength;
        }
        if (operation != null) {
            operation.registerCancelListener(mOperationCancelListener);
        }
        synchronized (mLock) {
            if (DEBUG_BATCH) {
                Slog.v(TAG, "set(" + operation + ") : type=" + type
@@ -1765,8 +1760,6 @@ class AlarmManagerService extends SystemService {
                        "Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID
                                + " reached for uid: " + UserHandle.formatUid(callingUid)
                                + ", callingPackage: " + callingPackage;
                mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
                        operation).sendToTarget();
                Slog.w(TAG, errorMsg);
                throw new IllegalStateException(errorMsg);
            }
@@ -1787,8 +1780,6 @@ class AlarmManagerService extends SystemService {
            if (ActivityManager.getService().isAppStartModeDisabled(callingUid, callingPackage)) {
                Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a
                        + " -- package not allowed to start");
                mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
                        operation).sendToTarget();
                return;
            }
        } catch (RemoteException e) {
@@ -2041,6 +2032,11 @@ class AlarmManagerService extends SystemService {
            }
        }

        @Override
        public void remove(PendingIntent pi) {
            mHandler.obtainMessage(AlarmHandler.REMOVE_FOR_CANCELED, pi).sendToTarget();
        }

        @Override
        public void registerInFlightListener(InFlightListener callback) {
            synchronized (mLock) {
@@ -2146,8 +2142,6 @@ class AlarmManagerService extends SystemService {
            synchronized (mLock) {
                removeLocked(operation, listener);
            }
            mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
                    operation).sendToTarget();
        }

        @Override
@@ -4151,7 +4145,7 @@ class AlarmManagerService extends SystemService {
        public static final int APP_STANDBY_BUCKET_CHANGED = 5;
        public static final int APP_STANDBY_PAROLE_CHANGED = 6;
        public static final int REMOVE_FOR_STOPPED = 7;
        public static final int UNREGISTER_CANCEL_LISTENER = 8;
        public static final int REMOVE_FOR_CANCELED = 8;

        AlarmHandler() {
            super(Looper.myLooper());
@@ -4234,10 +4228,10 @@ class AlarmManagerService extends SystemService {
                    }
                    break;

                case UNREGISTER_CANCEL_LISTENER:
                    final PendingIntent pi = (PendingIntent) msg.obj;
                    if (pi != null) {
                        pi.unregisterCancelListener(mOperationCancelListener);
                case REMOVE_FOR_CANCELED:
                    final PendingIntent operation = (PendingIntent) msg.obj;
                    synchronized (mLock) {
                        removeLocked(operation, null);
                    }
                    break;

@@ -4696,11 +4690,6 @@ class AlarmManagerService extends SystemService {
                                        Intent.EXTRA_ALARM_COUNT, alarm.count),
                                mDeliveryTracker, mHandler, null,
                                allowWhileIdle ? mIdleOptions : null);
                        if (alarm.repeatInterval == 0) {
                            // Keep the listener for repeating alarms until they get cancelled
                            mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
                                    alarm.operation).sendToTarget();
                        }
                    } catch (PendingIntent.CanceledException e) {
                        if (alarm.repeatInterval > 0) {
                            // This IntentSender is no longer valid, but this
+3 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.util.Slog;

import com.android.internal.os.IResultReceiver;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.AlarmManagerInternal;
import com.android.server.LocalServices;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.SafeActivityOptions;
@@ -293,6 +294,8 @@ public class PendingIntentController {
                    PendingIntentController::handlePendingIntentCancelled, this, callbacks);
            mH.sendMessage(m);
        }
        final AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
        ami.remove(new PendingIntent(rec));
    }

    private void handlePendingIntentCancelled(RemoteCallbackList<IResultReceiver> callbacks) {
+18 −14
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
@@ -35,6 +36,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.AlarmManagerService.ACTIVE_INDEX;
import static com.android.server.AlarmManagerService.AlarmHandler.APP_STANDBY_BUCKET_CHANGED;
import static com.android.server.AlarmManagerService.AlarmHandler.APP_STANDBY_PAROLE_CHANGED;
import static com.android.server.AlarmManagerService.AlarmHandler.REMOVE_FOR_CANCELED;
import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_LONG_TIME;
import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_SHORT_TIME;
import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION;
@@ -79,9 +81,9 @@ import android.provider.Settings;
import android.util.Log;
import android.util.SparseArray;

import androidx.test.filters.FlakyTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.dx.mockito.inline.extended.MockedVoidMethod;
import com.android.internal.annotations.GuardedBy;

import org.junit.After;
@@ -166,7 +168,6 @@ public class AlarmManagerServiceTest {
    }

    public class Injector extends AlarmManagerService.Injector {
        boolean mIsAutomotiveOverride;

        Injector(Context context) {
            super(context);
@@ -256,6 +257,9 @@ public class AlarmManagerServiceTest {
                .when(() -> LocalServices.getService(DeviceIdleController.LocalService.class));
        doReturn(mUsageStatsManagerInternal).when(
                () -> LocalServices.getService(UsageStatsManagerInternal.class));
        doCallRealMethod().when((MockedVoidMethod) () ->
                LocalServices.addService(eq(AlarmManagerInternal.class), any()));
        doCallRealMethod().when(() -> LocalServices.getService(AlarmManagerInternal.class));
        when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE),
                eq(UserHandle.getUserId(TEST_CALLING_UID)), anyLong()))
                .thenReturn(STANDBY_BUCKET_ACTIVE);
@@ -443,7 +447,6 @@ public class AlarmManagerServiceTest {
        assertEquals(expectedTriggerTime, mTestTimer.getElapsed());
    }

    @FlakyTest(bugId = 130313408)
    @Test
    public void testEarliestAlarmSet() {
        final PendingIntent pi6 = getNewMockPendingIntent();
@@ -661,11 +664,15 @@ public class AlarmManagerServiceTest {
                anyLong())).thenReturn(bucket);
        mAppStandbyListener.onAppIdleStateChanged(TEST_CALLING_PACKAGE,
                UserHandle.getUserId(TEST_CALLING_UID), false, bucket, 0);
        assertAndHandleMessageSync(APP_STANDBY_BUCKET_CHANGED);
    }

    private void assertAndHandleMessageSync(int what) {
        final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
        verify(mService.mHandler, atLeastOnce()).sendMessage(messageCaptor.capture());
        final Message lastMessage = messageCaptor.getValue();
        assertEquals("Unexpected message send to handler", lastMessage.what,
                APP_STANDBY_BUCKET_CHANGED);
                what);
        mService.mHandler.handleMessage(lastMessage);
    }

@@ -725,12 +732,7 @@ public class AlarmManagerServiceTest {

    private void assertAndHandleParoleChanged(boolean parole) {
        mAppStandbyListener.onParoleStateChanged(parole);
        final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
        verify(mService.mHandler, atLeastOnce()).sendMessage(messageCaptor.capture());
        final Message lastMessage = messageCaptor.getValue();
        assertEquals("Unexpected message send to handler", lastMessage.what,
                APP_STANDBY_PAROLE_CHANGED);
        mService.mHandler.handleMessage(lastMessage);
        assertAndHandleMessageSync(APP_STANDBY_PAROLE_CHANGED);
    }

    @Test
@@ -1033,12 +1035,13 @@ public class AlarmManagerServiceTest {
    }

    @Test
    public void alarmCountOnPendingIntentCancel() {
    public void alarmCountOnRemoveForCanceled() {
        final AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
        final PendingIntent pi = getNewMockPendingIntent();
        setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 123, pi);
        verify(pi).registerCancelListener(mService.mOperationCancelListener);
        setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 12345, pi);
        assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
        mService.mOperationCancelListener.onCancelled(pi);
        ami.remove(pi);
        assertAndHandleMessageSync(REMOVE_FOR_CANCELED);
        assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
    }

@@ -1047,5 +1050,6 @@ public class AlarmManagerServiceTest {
        if (mMockingSession != null) {
            mMockingSession.finishMocking();
        }
        LocalServices.removeServiceForTest(AlarmManagerInternal.class);
    }
}
Loading