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

Commit f506190a 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: d3283c51 am: 11871d47

parents 9bad62e6 11871d47
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -81,6 +81,10 @@ public class SystemUiSystemPropertiesFlags {
        /** Gating the logging of DND state change events. */
        /** Gating the logging of DND state change events. */
        public static final Flag LOG_DND_STATE_EVENTS =
        public static final Flag LOG_DND_STATE_EVENTS =
                releasedFlag("persist.sysui.notification.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. == ////
    //// == End of flags.  Everything below this line is the implementation. == ////
+46 −24
Original line number Original line 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 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.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.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_GROUP_PREFERENCES;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_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.Looper;
import android.os.Message;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.Process;
import android.os.Process;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ResultReceiver;
@@ -234,6 +237,7 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager;
import android.os.VibrationEffect;
import android.os.VibrationEffect;
import android.os.WorkSource;
import android.permission.PermissionManager;
import android.permission.PermissionManager;
import android.provider.DeviceConfig;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Settings;
@@ -559,6 +563,7 @@ public class NotificationManagerService extends SystemService {
    private PermissionHelper mPermissionHelper;
    private PermissionHelper mPermissionHelper;
    private UsageStatsManagerInternal mUsageStatsManagerInternal;
    private UsageStatsManagerInternal mUsageStatsManagerInternal;
    private TelecomManager mTelecomManager;
    private TelecomManager mTelecomManager;
    private PowerManager mPowerManager;
    private PostNotificationTrackerFactory mPostNotificationTrackerFactory;
    private PostNotificationTrackerFactory mPostNotificationTrackerFactory;
    final IBinder mForegroundToken = new Binder();
    final IBinder mForegroundToken = new Binder();
@@ -923,7 +928,7 @@ public class NotificationManagerService extends SystemService {
        if (oldFlags != flags) {
        if (oldFlags != flags) {
            summary.getSbn().getNotification().flags = flags;
            summary.getSbn().getNotification().flags = flags;
            mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground,
            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.
                        // want to adjust the flag behaviour.
                        mHandler.post(new EnqueueNotificationRunnable(r.getUser().getIdentifier(),
                        mHandler.post(new EnqueueNotificationRunnable(r.getUser().getIdentifier(),
                                r, true /* isAppForeground*/,
                                r, true /* isAppForeground*/,
                                mPostNotificationTrackerFactory.newTracker()));
                                mPostNotificationTrackerFactory.newTracker(null)));
                    }
                    }
                }
                }
            }
            }
@@ -1488,7 +1493,7 @@ public class NotificationManagerService extends SystemService {
                        mHandler.post(
                        mHandler.post(
                                new EnqueueNotificationRunnable(r.getUser().getIdentifier(), r,
                                new EnqueueNotificationRunnable(r.getUser().getIdentifier(), r,
                                        /* foreground= */ true,
                                        /* foreground= */ true,
                                        mPostNotificationTrackerFactory.newTracker()));
                                        mPostNotificationTrackerFactory.newTracker(null)));
                    }
                    }
                }
                }
            }
            }
@@ -2233,7 +2238,7 @@ public class NotificationManagerService extends SystemService {
            UsageStatsManagerInternal usageStatsManagerInternal,
            UsageStatsManagerInternal usageStatsManagerInternal,
            TelecomManager telecomManager, NotificationChannelLogger channelLogger,
            TelecomManager telecomManager, NotificationChannelLogger channelLogger,
            SystemUiSystemPropertiesFlags.FlagResolver flagResolver,
            SystemUiSystemPropertiesFlags.FlagResolver flagResolver,
            PermissionManager permissionManager,
            PermissionManager permissionManager, PowerManager powerManager,
            PostNotificationTrackerFactory postNotificationTrackerFactory) {
            PostNotificationTrackerFactory postNotificationTrackerFactory) {
        mHandler = handler;
        mHandler = handler;
        Resources resources = getContext().getResources();
        Resources resources = getContext().getResources();
@@ -2265,6 +2270,7 @@ public class NotificationManagerService extends SystemService {
        mDpm = dpm;
        mDpm = dpm;
        mUm = userManager;
        mUm = userManager;
        mTelecomManager = telecomManager;
        mTelecomManager = telecomManager;
        mPowerManager = powerManager;
        mPostNotificationTrackerFactory = postNotificationTrackerFactory;
        mPostNotificationTrackerFactory = postNotificationTrackerFactory;
        mPlatformCompat = IPlatformCompat.Stub.asInterface(
        mPlatformCompat = IPlatformCompat.Stub.asInterface(
                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
@@ -2568,6 +2574,7 @@ public class NotificationManagerService extends SystemService {
                getContext().getSystemService(TelecomManager.class),
                getContext().getSystemService(TelecomManager.class),
                new NotificationChannelLoggerImpl(), SystemUiSystemPropertiesFlags.getResolver(),
                new NotificationChannelLoggerImpl(), SystemUiSystemPropertiesFlags.getResolver(),
                getContext().getSystemService(PermissionManager.class),
                getContext().getSystemService(PermissionManager.class),
                getContext().getSystemService(PowerManager.class),
                new PostNotificationTrackerFactory() {});
                new PostNotificationTrackerFactory() {});
        publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
        publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
@@ -2684,7 +2691,7 @@ public class NotificationManagerService extends SystemService {
                    final boolean isAppForeground =
                    final boolean isAppForeground =
                            mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
                            mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
                    mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
                    mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
                            mPostNotificationTrackerFactory.newTracker()));
                            mPostNotificationTrackerFactory.newTracker(null)));
                }
                }
            }
            }
@@ -6574,7 +6581,7 @@ public class NotificationManagerService extends SystemService {
    void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
    void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
            final int callingPid, final String tag, final int id, final Notification notification,
            final int callingPid, final String tag, final int id, final Notification notification,
            int incomingUserId, boolean postSilently) {
            int incomingUserId, boolean postSilently) {
        PostNotificationTracker tracker = mPostNotificationTrackerFactory.newTracker();
        PostNotificationTracker tracker = acquireWakeLockForPost(pkg, callingUid);
        boolean enqueued = false;
        boolean enqueued = false;
        try {
        try {
            enqueued = enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id,
            enqueued = enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id,
@@ -6586,6 +6593,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
     * @return True if we successfully processed the notification and handed off the task of
     * enqueueing it to a background thread; false otherwise.
     * enqueueing it to a background thread; false otherwise.
@@ -7105,7 +7128,7 @@ public class NotificationManagerService extends SystemService {
                            mHandler.post(
                            mHandler.post(
                                    new NotificationManagerService.EnqueueNotificationRunnable(
                                    new NotificationManagerService.EnqueueNotificationRunnable(
                                            r.getUser().getIdentifier(), r, isAppForeground,
                                            r.getUser().getIdentifier(), r, isAppForeground,
                                            mPostNotificationTrackerFactory.newTracker()));
                                            mPostNotificationTrackerFactory.newTracker(null)));
                        }
                        }
                    }
                    }
                }
                }
@@ -12137,20 +12160,20 @@ public class NotificationManagerService extends SystemService {
    }
    }
    interface PostNotificationTrackerFactory {
    interface PostNotificationTrackerFactory {
        default PostNotificationTracker newTracker() {
        default PostNotificationTracker newTracker(@Nullable WakeLock optionalWakelock) {
            return new PostNotificationTracker();
            return new PostNotificationTracker(optionalWakelock);
        }
        }
    }
    }
    static class PostNotificationTracker {
    static class PostNotificationTracker {
        @ElapsedRealtimeLong private final long mStartTime;
        @ElapsedRealtimeLong private final long mStartTime;
        @Nullable private NotificationRecordLogger.NotificationReported mReport;
        @Nullable private final WakeLock mWakeLock;
        private boolean mOngoing;
        private boolean mOngoing;
        @VisibleForTesting
        @VisibleForTesting
        PostNotificationTracker() {
        PostNotificationTracker(@Nullable WakeLock wakeLock) {
            // TODO(b/275044361): (Conditionally) receive a wakelock.
            mStartTime = SystemClock.elapsedRealtime();
            mStartTime = SystemClock.elapsedRealtime();
            mWakeLock = wakeLock;
            mOngoing = true;
            mOngoing = true;
            if (DBG) {
            if (DBG) {
                Slog.d(TAG, "PostNotification: Started");
                Slog.d(TAG, "PostNotification: Started");
@@ -12168,9 +12191,8 @@ public class NotificationManagerService extends SystemService {
        }
        }
        /**
        /**
         * Cancels the tracker (TODO(b/275044361): releasing the acquired WakeLock). Either
         * Cancels the tracker (releasing the acquired WakeLock). Either {@link #finish} or
         * {@link #finish} or {@link #cancel} (exclusively) should be called on this object before
         * {@link #cancel} (exclusively) should be called on this object before it's discarded.
         * it's discarded.
         */
         */
        void cancel() {
        void cancel() {
            if (!isOngoing()) {
            if (!isOngoing()) {
@@ -12178,9 +12200,9 @@ public class NotificationManagerService extends SystemService {
                return;
                return;
            }
            }
            mOngoing = false;
            mOngoing = false;
            if (mWakeLock != null) {
            // TODO(b/275044361): Release wakelock.
                Binder.withCleanCallingIdentity(() -> mWakeLock.release());
            }
            if (DBG) {
            if (DBG) {
                long elapsedTime = SystemClock.elapsedRealtime() - mStartTime;
                long elapsedTime = SystemClock.elapsedRealtime() - mStartTime;
                Slog.d(TAG, TextUtils.formatSimple("PostNotification: Abandoned after %d ms",
                Slog.d(TAG, TextUtils.formatSimple("PostNotification: Abandoned after %d ms",
@@ -12189,9 +12211,9 @@ public class NotificationManagerService extends SystemService {
        }
        }
        /**
        /**
         * Finishes the tracker (TODO(b/275044361): releasing the acquired WakeLock) and returns the
         * Finishes the tracker (releasing the acquired WakeLock) and returns the time elapsed since
         * time elapsed since the operation started, in milliseconds. Either {@link #finish} or
         * the operation started, in milliseconds. Either {@link #finish} or {@link #cancel}
         * {@link #cancel} (exclusively) should be called on this object before it's discarded.
         * (exclusively) should be called on this object before it's discarded.
         */
         */
        @DurationMillisLong
        @DurationMillisLong
        long finish() {
        long finish() {
@@ -12201,9 +12223,9 @@ public class NotificationManagerService extends SystemService {
                return elapsedTime;
                return elapsedTime;
            }
            }
            mOngoing = false;
            mOngoing = false;
            if (mWakeLock != null) {
            // TODO(b/275044361): Release wakelock.
                Binder.withCleanCallingIdentity(() -> mWakeLock.release());
            }
            if (DBG) {
            if (DBG) {
                Slog.d(TAG,
                Slog.d(TAG,
                        TextUtils.formatSimple("PostNotification: Finished in %d ms", elapsedTime));
                        TextUtils.formatSimple("PostNotification: Finished in %d ms", elapsedTime));
+2 −0
Original line number Original line 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" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
    <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_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.MANAGE_USERS" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
    <uses-permission android:name="android.permission.ACCESS_NOTIFICATIONS" />
    <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.WRITE_ALLOWLISTED_DEVICE_CONFIG" />
    <uses-permission android:name="android.permission.READ_WRITE_SYNC_DISABLED_MODE_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.ACCESS_KEYGUARD_SECURE_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />


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

File changed.

Preview size limit exceeded, changes collapsed.

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