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

Commit 862df2f7 authored by Matías Hernández's avatar Matías Hernández Committed by Automerger Merge Worker
Browse files

Merge "Acquire WakeLocks for posting notifications" into udc-dev am:...

Merge "Acquire WakeLocks for posting notifications" into udc-dev am: d3283c51 am: 817536d0 am: f6ce4a71

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23518056



Change-Id: I8aae9a9f465edfc268c6d039533e3846d517d2a9
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents af11e8e7 f6ce4a71
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -81,6 +81,10 @@ public class SystemUiSystemPropertiesFlags {
        /** Gating the logging of DND state change events. */
        public static final Flag LOG_DND_STATE_EVENTS =
                releasedFlag("persist.sysui.notification.log_dnd_state_events");

        /** Gating the holding of WakeLocks until NLSes are told about a new notification. */
        public static final Flag WAKE_LOCK_FOR_POSTING_NOTIFICATION =
                devFlag("persist.sysui.notification.wake_lock_for_posting_notification");
    }

    //// == End of flags.  Everything below this line is the implementation. == ////
+46 −24
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ import static android.service.notification.NotificationListenerService.TRIM_LIGH
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING;
import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.WAKE_LOCK_FOR_POSTING_NOTIFICATION;
import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
@@ -223,6 +224,8 @@ import android.os.IInterface;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -234,6 +237,7 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.VibrationEffect;
import android.os.WorkSource;
import android.permission.PermissionManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -559,6 +563,7 @@ public class NotificationManagerService extends SystemService {
    private PermissionHelper mPermissionHelper;
    private UsageStatsManagerInternal mUsageStatsManagerInternal;
    private TelecomManager mTelecomManager;
    private PowerManager mPowerManager;
    private PostNotificationTrackerFactory mPostNotificationTrackerFactory;
    final IBinder mForegroundToken = new Binder();
@@ -923,7 +928,7 @@ public class NotificationManagerService extends SystemService {
        if (oldFlags != flags) {
            summary.getSbn().getNotification().flags = flags;
            mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground,
                    mPostNotificationTrackerFactory.newTracker()));
                    mPostNotificationTrackerFactory.newTracker(null)));
        }
    }
@@ -1457,7 +1462,7 @@ public class NotificationManagerService extends SystemService {
                        // want to adjust the flag behaviour.
                        mHandler.post(new EnqueueNotificationRunnable(r.getUser().getIdentifier(),
                                r, true /* isAppForeground*/,
                                mPostNotificationTrackerFactory.newTracker()));
                                mPostNotificationTrackerFactory.newTracker(null)));
                    }
                }
            }
@@ -1488,7 +1493,7 @@ public class NotificationManagerService extends SystemService {
                        mHandler.post(
                                new EnqueueNotificationRunnable(r.getUser().getIdentifier(), r,
                                        /* foreground= */ true,
                                        mPostNotificationTrackerFactory.newTracker()));
                                        mPostNotificationTrackerFactory.newTracker(null)));
                    }
                }
            }
@@ -2233,7 +2238,7 @@ public class NotificationManagerService extends SystemService {
            UsageStatsManagerInternal usageStatsManagerInternal,
            TelecomManager telecomManager, NotificationChannelLogger channelLogger,
            SystemUiSystemPropertiesFlags.FlagResolver flagResolver,
            PermissionManager permissionManager,
            PermissionManager permissionManager, PowerManager powerManager,
            PostNotificationTrackerFactory postNotificationTrackerFactory) {
        mHandler = handler;
        Resources resources = getContext().getResources();
@@ -2265,6 +2270,7 @@ public class NotificationManagerService extends SystemService {
        mDpm = dpm;
        mUm = userManager;
        mTelecomManager = telecomManager;
        mPowerManager = powerManager;
        mPostNotificationTrackerFactory = postNotificationTrackerFactory;
        mPlatformCompat = IPlatformCompat.Stub.asInterface(
                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
@@ -2568,6 +2574,7 @@ public class NotificationManagerService extends SystemService {
                getContext().getSystemService(TelecomManager.class),
                new NotificationChannelLoggerImpl(), SystemUiSystemPropertiesFlags.getResolver(),
                getContext().getSystemService(PermissionManager.class),
                getContext().getSystemService(PowerManager.class),
                new PostNotificationTrackerFactory() {});
        publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
@@ -2684,7 +2691,7 @@ public class NotificationManagerService extends SystemService {
                    final boolean isAppForeground =
                            mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
                    mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
                            mPostNotificationTrackerFactory.newTracker()));
                            mPostNotificationTrackerFactory.newTracker(null)));
                }
            }
@@ -6577,7 +6584,7 @@ public class NotificationManagerService extends SystemService {
    void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
            final int callingPid, final String tag, final int id, final Notification notification,
            int incomingUserId, boolean postSilently) {
        PostNotificationTracker tracker = mPostNotificationTrackerFactory.newTracker();
        PostNotificationTracker tracker = acquireWakeLockForPost(pkg, callingUid);
        boolean enqueued = false;
        try {
            enqueued = enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id,
@@ -6589,6 +6596,22 @@ public class NotificationManagerService extends SystemService {
        }
    }
    private PostNotificationTracker acquireWakeLockForPost(String pkg, int uid) {
        if (mFlagResolver.isEnabled(WAKE_LOCK_FOR_POSTING_NOTIFICATION)) {
            // The package probably doesn't have WAKE_LOCK permission and should not require it.
            return Binder.withCleanCallingIdentity(() -> {
                WakeLock wakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                        "NotificationManagerService:post:" + pkg);
                wakeLock.setWorkSource(new WorkSource(uid, pkg));
                // TODO(b/275044361): Adjust to a more reasonable number when we have the data.
                wakeLock.acquire(30_000);
                return mPostNotificationTrackerFactory.newTracker(wakeLock);
            });
        } else {
            return mPostNotificationTrackerFactory.newTracker(null);
        }
    }
    /**
     * @return True if we successfully processed the notification and handed off the task of
     * enqueueing it to a background thread; false otherwise.
@@ -7108,7 +7131,7 @@ public class NotificationManagerService extends SystemService {
                            mHandler.post(
                                    new NotificationManagerService.EnqueueNotificationRunnable(
                                            r.getUser().getIdentifier(), r, isAppForeground,
                                            mPostNotificationTrackerFactory.newTracker()));
                                            mPostNotificationTrackerFactory.newTracker(null)));
                        }
                    }
                }
@@ -12140,20 +12163,20 @@ public class NotificationManagerService extends SystemService {
    }
    interface PostNotificationTrackerFactory {
        default PostNotificationTracker newTracker() {
            return new PostNotificationTracker();
        default PostNotificationTracker newTracker(@Nullable WakeLock optionalWakelock) {
            return new PostNotificationTracker(optionalWakelock);
        }
    }
    static class PostNotificationTracker {
        @ElapsedRealtimeLong private final long mStartTime;
        @Nullable private NotificationRecordLogger.NotificationReported mReport;
        @Nullable private final WakeLock mWakeLock;
        private boolean mOngoing;
        @VisibleForTesting
        PostNotificationTracker() {
            // TODO(b/275044361): (Conditionally) receive a wakelock.
        PostNotificationTracker(@Nullable WakeLock wakeLock) {
            mStartTime = SystemClock.elapsedRealtime();
            mWakeLock = wakeLock;
            mOngoing = true;
            if (DBG) {
                Slog.d(TAG, "PostNotification: Started");
@@ -12171,9 +12194,8 @@ public class NotificationManagerService extends SystemService {
        }
        /**
         * Cancels the tracker (TODO(b/275044361): releasing the acquired WakeLock). Either
         * {@link #finish} or {@link #cancel} (exclusively) should be called on this object before
         * it's discarded.
         * Cancels the tracker (releasing the acquired WakeLock). Either {@link #finish} or
         * {@link #cancel} (exclusively) should be called on this object before it's discarded.
         */
        void cancel() {
            if (!isOngoing()) {
@@ -12181,9 +12203,9 @@ public class NotificationManagerService extends SystemService {
                return;
            }
            mOngoing = false;
            // TODO(b/275044361): Release wakelock.
            if (mWakeLock != null) {
                Binder.withCleanCallingIdentity(() -> mWakeLock.release());
            }
            if (DBG) {
                long elapsedTime = SystemClock.elapsedRealtime() - mStartTime;
                Slog.d(TAG, TextUtils.formatSimple("PostNotification: Abandoned after %d ms",
@@ -12192,9 +12214,9 @@ public class NotificationManagerService extends SystemService {
        }
        /**
         * Finishes the tracker (TODO(b/275044361): releasing the acquired WakeLock) and returns the
         * time elapsed since the operation started, in milliseconds. Either {@link #finish} or
         * {@link #cancel} (exclusively) should be called on this object before it's discarded.
         * Finishes the tracker (releasing the acquired WakeLock) and returns the time elapsed since
         * the operation started, in milliseconds. Either {@link #finish} or {@link #cancel}
         * (exclusively) should be called on this object before it's discarded.
         */
        @DurationMillisLong
        long finish() {
@@ -12204,9 +12226,9 @@ public class NotificationManagerService extends SystemService {
                return elapsedTime;
            }
            mOngoing = false;
            // TODO(b/275044361): Release wakelock.
            if (mWakeLock != null) {
                Binder.withCleanCallingIdentity(() -> mWakeLock.release());
            }
            if (DBG) {
                Slog.d(TAG,
                        TextUtils.formatSimple("PostNotification: Finished in %d ms", elapsedTime));
+2 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
    <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
    <uses-permission android:name="android.permission.MANAGE_USERS" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
    <uses-permission android:name="android.permission.ACCESS_NOTIFICATIONS" />
@@ -36,6 +37,7 @@
    <uses-permission android:name="android.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG" />
    <uses-permission android:name="android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG" />
    <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application android:debuggable="true">
        <uses-library android:name="android.test.runner" />
+162 −24

File changed.

Preview size limit exceeded, changes collapsed.

+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.os.Looper;
import android.os.PowerManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionManager;
@@ -169,6 +170,7 @@ public class RoleObserverTest extends UiServiceTestCase {
                    mock(UsageStatsManagerInternal.class), mock(TelecomManager.class),
                    mock(NotificationChannelLogger.class), new TestableFlagResolver(),
                    mock(PermissionManager.class),
                    mock(PowerManager.class),
                    new NotificationManagerService.PostNotificationTrackerFactory() {});
        } catch (SecurityException e) {
            if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {