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

Commit 0ba4c710 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #29506774: Foreground Service Can Avoid Notification Requirement

Don't cancel the notification if there are other foreground
services using the same notification ID.

Change-Id: I02a49d9a07af0203e59e70be2dc6773f3cefee47
parent fea7cfce
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -699,7 +699,7 @@ public final class ActiveServices {
                        throw new IllegalArgumentException("null notification");
                    }
                    if (r.foregroundId != id) {
                        r.cancelNotification();
                        cancelForegroudNotificationLocked(r);
                        r.foregroundId = id;
                    }
                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -721,7 +721,7 @@ public final class ActiveServices {
                        }
                    }
                    if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
                        r.cancelNotification();
                        cancelForegroudNotificationLocked(r);
                        r.foregroundId = 0;
                        r.foregroundNoti = null;
                    } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
@@ -738,6 +738,27 @@ public final class ActiveServices {
        }
    }

    private void cancelForegroudNotificationLocked(ServiceRecord r) {
        if (r.foregroundId != 0) {
            // First check to see if this app has any other active foreground services
            // with the same notification ID.  If so, we shouldn't actually cancel it,
            // because that would wipe away the notification that still needs to be shown
            // due the other service.
            ServiceMap sm = getServiceMap(r.userId);
            if (sm != null) {
                for (int i = sm.mServicesByName.size()-1; i >= 0; i--) {
                    ServiceRecord other = sm.mServicesByName.valueAt(i);
                    if (other.foregroundId == r.foregroundId
                            && other.packageName.equals(r.packageName)) {
                        // Found one!  Abort the cancel.
                        return;
                    }
                }
            }
            r.cancelNotification();
        }
    }

    private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
        boolean anyForeground = false;
        for (int i=proc.services.size()-1; i>=0; i--) {
@@ -1560,7 +1581,7 @@ public final class ActiveServices {
            r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
        }

        r.cancelNotification();
        cancelForegroudNotificationLocked(r);

        mAm.mHandler.removeCallbacks(r.restarter);
        mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
@@ -2022,7 +2043,7 @@ public final class ActiveServices {
            }
        }

        r.cancelNotification();
        cancelForegroudNotificationLocked(r);
        r.isForeground = false;
        r.foregroundId = 0;
        r.foregroundNoti = null;
+18 −20
Original line number Diff line number Diff line
@@ -543,7 +543,6 @@ final class ServiceRecord extends Binder {
    }
    
    public void cancelNotification() {
        if (foregroundId != 0) {
        // Do asynchronous communication with notification manager to
        // avoid deadlocks.
        final String localPackageName = packageName;
@@ -564,7 +563,6 @@ final class ServiceRecord extends Binder {
            }
        });
    }
    }

    public void stripForegroundServiceFlagFromNotification() {
        if (foregroundId == 0) {