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

Commit febf6349 authored by Arne Coucheron's avatar Arne Coucheron
Browse files

Revert "Fix alarm not firing in memory-pressure situations"

I have two different devices, both of which are experiencing issues
with randomly missed alarms in N. I can see in the logs that the
device wakes up in time, and it's aware that it has to fire an
alarm. So it gives the order to fire, but the order never reaches the
firing squad.

Testing this revert, both by myself and users, shows that not a single
alarm is missed. It wakes up and fires the alarm as it should every
time.

Note: CAF hijacked some of the code that Google removed in the patch,
and modified it for their own use, so I had to slightly adapt the
revert to that.

This reverts commit b76aa50f.

Change-Id: I3eeb85dec208cd0022c3d037a403bbe1a5d86e28
parent bf18903f
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ final class AlarmNotifications {
                AlarmStateManager.ALARM_DELETE_TAG, instance,
                AlarmInstance.HIDE_NOTIFICATION_STATE);
        final int id = instance.hashCode();
        builder.setDeleteIntent(PendingIntent.getService(context, id,
        builder.setDeleteIntent(PendingIntent.getBroadcast(context, id,
                hideIntent, PendingIntent.FLAG_UPDATE_CURRENT));

        // Setup up dismiss action
@@ -118,7 +118,7 @@ final class AlarmNotifications {
                AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.PREDISMISSED_STATE);
        builder.addAction(R.drawable.ic_alarm_off_24dp,
                context.getString(R.string.alarm_alert_dismiss_text),
                PendingIntent.getService(context, id,
                PendingIntent.getBroadcast(context, id,
                        dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));

        // Setup content action if instance is owned by alarm
@@ -162,7 +162,7 @@ final class AlarmNotifications {
        final int id = instance.hashCode();
        builder.addAction(R.drawable.ic_alarm_off_24dp,
                context.getString(R.string.alarm_alert_dismiss_text),
                PendingIntent.getService(context, id,
                PendingIntent.getBroadcast(context, id,
                        dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));

        // Setup content action if instance is owned by alarm
@@ -333,7 +333,7 @@ final class AlarmNotifications {
        final int id = instance.hashCode();
        builder.addAction(R.drawable.ic_alarm_off_24dp,
                context.getString(R.string.alarm_alert_dismiss_text),
                PendingIntent.getService(context, id,
                PendingIntent.getBroadcast(context, id,
                        dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));

        // Setup content action if instance is owned by alarm
@@ -379,7 +379,7 @@ final class AlarmNotifications {
        // Setup dismiss intent
        Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
                AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
        builder.setDeleteIntent(PendingIntent.getService(context, id,
        builder.setDeleteIntent(PendingIntent.getBroadcast(context, id,
                dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));

        // Setup content intent
@@ -422,7 +422,7 @@ final class AlarmNotifications {
        Intent snoozeIntent = AlarmStateManager.createStateChangeIntent(service,
                AlarmStateManager.ALARM_SNOOZE_TAG, instance, AlarmInstance.SNOOZE_STATE);
        snoozeIntent.putExtra(AlarmStateManager.FROM_NOTIFICATION_EXTRA, true);
        PendingIntent snoozePendingIntent = PendingIntent.getService(service,
        PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(service,
                ALARM_FIRING_NOTIFICATION_ID, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        notification.addAction(R.drawable.ic_snooze_24dp,
                resources.getString(R.string.alarm_alert_snooze_text), snoozePendingIntent);
@@ -431,7 +431,7 @@ final class AlarmNotifications {
        Intent dismissIntent = AlarmStateManager.createStateChangeIntent(service,
                AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
        dismissIntent.putExtra(AlarmStateManager.FROM_NOTIFICATION_EXTRA, true);
        PendingIntent dismissPendingIntent = PendingIntent.getService(service,
        PendingIntent dismissPendingIntent = PendingIntent.getBroadcast(service,
                ALARM_FIRING_NOTIFICATION_ID, dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        notification.addAction(R.drawable.ic_alarm_off_24dp,
                resources.getString(R.string.alarm_alert_dismiss_text),
+26 −22
Original line number Diff line number Diff line
@@ -120,6 +120,14 @@ public class AlarmService extends Service {
    private int mFlipAction;
    private int mShakeAction;

    public static void startAlarm(Context context, AlarmInstance instance) {
        final Intent intent = AlarmInstance.createIntent(context, AlarmService.class, instance.mId)
                .setAction(AlarmStateManager.CHANGE_STATE_ACTION);
        intent.putExtra(AlarmStateManager.ALARM_STATE_EXTRA, AlarmInstance.FIRED_STATE);
        AlarmAlertWakeLock.acquireCpuWakeLock(context);
        context.startService(intent);
    }

    private void startAlarm(AlarmInstance instance) {
        LogUtils.v("AlarmService.start with instance: " + instance.mId);
        if (mCurrentAlarm != null) {
@@ -129,6 +137,8 @@ public class AlarmService extends Service {

        AlarmAlertWakeLock.acquireCpuWakeLock(this);

        Events.sendEvent(R.string.category_alarm, R.string.action_fire, 0);

        mCurrentAlarm = instance;
        AlarmNotifications.showAlarmNotification(this, mCurrentAlarm);
        mTelephonyManager.listen(mPhoneStateListener.init(), PhoneStateListener.LISTEN_CALL_STATE);
@@ -216,11 +226,6 @@ public class AlarmService extends Service {
        final long instanceId = AlarmInstance.getId(intent.getData());
        switch (intent.getAction()) {
            case AlarmStateManager.CHANGE_STATE_ACTION:
                AlarmStateManager.handleIntent(this, intent);

                // If state is changed to firing, actually fire the alarm!
                final int alarmState = intent.getIntExtra(AlarmStateManager.ALARM_STATE_EXTRA, -1);
                if (alarmState == AlarmInstance.FIRED_STATE) {
                final ContentResolver cr = this.getContentResolver();
                final AlarmInstance instance = AlarmInstance.getInstance(cr, instanceId);
                if (instance == null) {
@@ -237,7 +242,6 @@ public class AlarmService extends Service {
                    break;
                }
                startAlarm(instance);
                }
                break;
            case STOP_ALARM_ACTION:
                if (mCurrentAlarm != null && mCurrentAlarm.mId != instanceId) {
@@ -282,7 +286,7 @@ public class AlarmService extends Service {
            }

            if (state != TelephonyManager.CALL_STATE_IDLE && state != mPhoneCallState) {
                startService(AlarmStateManager.createStateChangeIntent(AlarmService.this,
                sendBroadcast(AlarmStateManager.createStateChangeIntent(AlarmService.this,
                        "AlarmService", mCurrentAlarm, AlarmInstance.MISSED_STATE));
            }
        }
@@ -429,13 +433,13 @@ public class AlarmService extends Service {
        switch (action) {
            case ALARM_SNOOZE:
                // Setup Snooze Action
                startService(AlarmStateManager.createStateChangeIntent(this,
                sendBroadcast(AlarmStateManager.createStateChangeIntent(this,
                        AlarmStateManager.ALARM_SNOOZE_TAG, mCurrentAlarm,
                        AlarmInstance.SNOOZE_STATE));
                break;
            case ALARM_DISMISS:
                // Setup Dismiss Action
                startService(AlarmStateManager.createStateChangeIntent(this,
                sendBroadcast(AlarmStateManager.createStateChangeIntent(this,
                        AlarmStateManager.ALARM_DISMISS_TAG, mCurrentAlarm,
                        AlarmInstance.DISMISSED_STATE));
                break;
+6 −11
Original line number Diff line number Diff line
@@ -319,13 +319,7 @@ public final class AlarmStateManager extends BroadcastReceiver {
     */
    public static Intent createStateChangeIntent(Context context, String tag,
            AlarmInstance instance, Integer state) {
        // This intent is directed to AlarmService, though the actual handling of it occurs here
        // in AlarmStateManager. The reason is that evidence exists showing the jump between the
        // broadcast receiver (AlarmStateManager) and service (AlarmService) can be thwarted by the
        // Out Of Memory killer. If clock is killed during that jump, firing an alarm can fail to
        // occur. To be safer, the call begins in AlarmService, which has the power to display the
        // firing alarm if needed, so no jump is needed.
        Intent intent = AlarmInstance.createIntent(context, AlarmService.class, instance.mId);
        Intent intent = AlarmInstance.createIntent(context, AlarmStateManager.class, instance.mId);
        intent.setAction(CHANGE_STATE_ACTION);
        intent.addCategory(tag);
        intent.putExtra(ALARM_GLOBAL_ID_EXTRA, DataModel.getDataModel().getGlobalIntentId());
@@ -470,7 +464,8 @@ public final class AlarmStateManager extends BroadcastReceiver {
                    instance.mId);
        }

        Events.sendAlarmEvent(R.string.action_fire, 0);
        // Start the alarm and schedule timeout timer for it
        AlarmService.startAlarm(context, instance);

        Calendar timeout = instance.getTimeout();
        if (timeout != null) {
@@ -916,7 +911,7 @@ public final class AlarmStateManager extends BroadcastReceiver {
        });
    }

    public static void handleIntent(Context context, Intent intent) {
    private void handleIntent(Context context, Intent intent) {
        final String action = intent.getAction();
        LogUtils.v("AlarmStateManager received intent " + intent);
        if (CHANGE_STATE_ACTION.equals(action)) {
@@ -1042,7 +1037,7 @@ public final class AlarmStateManager extends BroadcastReceiver {
                    createStateChangeIntent(context, ALARM_MANAGER_TAG, instance, newState);
            // Treat alarm state change as high priority, use foreground broadcasts
            stateChangeIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
            PendingIntent pendingIntent = PendingIntent.getForegroundService(context, instance.hashCode(),
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, instance.hashCode(),
                    stateChangeIntent, PendingIntent.FLAG_UPDATE_CURRENT);

            final AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE);
@@ -1059,7 +1054,7 @@ public final class AlarmStateManager extends BroadcastReceiver {
            LogUtils.v("Canceling instance " + instance.mId + " timers");

            // Create a PendingIntent that will match any one set for this instance
            PendingIntent pendingIntent = PendingIntent.getService(context, instance.hashCode(),
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, instance.hashCode(),
                    createStateChangeIntent(context, ALARM_MANAGER_TAG, instance, null),
                    PendingIntent.FLAG_NO_CREATE);

+1 −1
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ public final class AlarmTimeClickHandler {
        final Intent dismissIntent = AlarmStateManager.createStateChangeIntent(
                mContext, AlarmStateManager.ALARM_DISMISS_TAG, alarmInstance,
                AlarmInstance.PREDISMISSED_STATE);
        mContext.startService(dismissIntent);
        mContext.sendBroadcast(dismissIntent);
        mAlarmUpdateHandler.showPredismissToast(alarmInstance);
    }

+7 −8
Original line number Diff line number Diff line
@@ -784,25 +784,24 @@ final class TimerModel {
     * displayed whether the application is open or not.
     */
    private void updateHeadsUpNotification() {
        // Nothing can be done with the heads-up notification without a valid service reference.
        if (mService == null) {
            return;
        }

        final List<Timer> expired = getExpiredTimers();

        // If no expired timers exist, stop the service (which cancels the foreground notification).
        if (expired.isEmpty()) {
            if (mService != null) {
                mService.stopSelf();
                mService = null;
            }
            return;
        }

        // Otherwise build and post a foreground notification reflecting the latest expired timers.
        final Notification notification = mNotificationBuilder.buildHeadsUp(mContext, expired);
        final int notificationId = mNotificationModel.getExpiredTimerNotificationId();
        if (mService != null) {
            mService.startForeground(notificationId, notification);
        }
    }

    /**
     * Update the timer notification in response to a locale change.