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

Commit 7af8fe3e authored by Rohan Shah's avatar Rohan Shah Committed by Android (Google) Code Review
Browse files

Merge "Add knobs for tweaking blocking helper thresholds" into pi-dev

parents 4179c5ca 0350dab5
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -12570,6 +12570,28 @@ public final class Settings {
        public static final String NOTIFICATION_SNOOZE_OPTIONS =
                "notification_snooze_options";
        /**
         * Settings key for the ratio of notification dismissals to notification views - one of the
         * criteria for showing the notification blocking helper.
         *
         * <p>The value is a float ranging from 0.0 to 1.0 (the closer to 0.0, the more intrusive
         * the blocking helper will be).
         *
         * @hide
         */
        public static final String BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT =
                "blocking_helper_dismiss_to_view_ratio";
        /**
         * Settings key for the longest streak of dismissals  - one of the criteria for showing the
         * notification blocking helper.
         *
         * <p>The value is an integer greater than 0.
         *
         * @hide
         */
        public static final String BLOCKING_HELPER_STREAK_LIMIT = "blocking_helper_streak_limit";
        /**
         * Configuration flags for SQLite Compatibility WAL. Encoded as a key-value list, separated
         * by commas. E.g.: compatibility_wal_supported=true, wal_syncmode=OFF
+4 −1
Original line number Diff line number Diff line
@@ -48,7 +48,10 @@ public abstract class NotificationAssistantService extends NotificationListenerS
    public static final String SERVICE_INTERFACE
            = "android.service.notification.NotificationAssistantService";

    private Handler mHandler;
    /**
     * @hide
     */
    protected Handler mHandler;

    @Override
    protected void attachBaseContext(Context base) {
+2 −0
Original line number Diff line number Diff line
@@ -131,6 +131,8 @@ public class SettingsBackupTest {
                    Settings.Global.BLE_SCAN_LOW_LATENCY_WINDOW_MS,
                    Settings.Global.BLE_SCAN_LOW_LATENCY_INTERVAL_MS,
                    Settings.Global.BLE_SCAN_BACKGROUND_MODE,
                    Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
                    Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
                    Settings.Global.BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX,
                    Settings.Global.BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX,
                    Settings.Global.BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX,
+75 −6
Original line number Diff line number Diff line
@@ -17,16 +17,20 @@
package android.ext.services.notification;

import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.service.notification.NotificationListenerService.Ranking
        .USER_SENTIMENT_NEGATIVE;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;

import android.app.INotificationManager;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.ext.services.R;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.storage.StorageManager;
import android.provider.Settings;
import android.service.notification.Adjustment;
import android.service.notification.NotificationAssistantService;
import android.service.notification.NotificationStats;
@@ -74,9 +78,12 @@ public class Assistant extends NotificationAssistantService {
        PREJUDICAL_DISMISSALS.add(REASON_LISTENER_CANCEL);
    }

    private float mDismissToViewRatioLimit;
    private int mStreakLimit;

    // key : impressions tracker
    // TODO: prune deleted channels and apps
    ArrayMap<String, ChannelImpressions> mkeyToImpressions = new ArrayMap<>();
    final ArrayMap<String, ChannelImpressions> mkeyToImpressions = new ArrayMap<>();
    // SBN key : channel id
    ArrayMap<String, String> mLiveNotifications = new ArrayMap<>();

@@ -86,6 +93,14 @@ public class Assistant extends NotificationAssistantService {
    public Assistant() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // Contexts are correctly hooked up by the creation step, which is required for the observer
        // to be hooked up/initialized.
        new SettingsObserver(mHandler);
    }

    private void loadFile() {
        if (DEBUG) Slog.d(TAG, "loadFile");
        AsyncTask.execute(() -> {
@@ -120,7 +135,7 @@ public class Assistant extends NotificationAssistantService {
                    continue;
                }
                String key = parser.getAttributeValue(null, ATT_KEY);
                ChannelImpressions ci = new ChannelImpressions();
                ChannelImpressions ci = createChannelImpressionsWithThresholds();
                ci.populateFromXml(parser);
                synchronized (mkeyToImpressions) {
                    ci.append(mkeyToImpressions.get(key));
@@ -184,7 +199,7 @@ public class Assistant extends NotificationAssistantService {
                String key = getKey(
                        sbn.getPackageName(), sbn.getUserId(), ranking.getChannel().getId());
                ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
                        new ChannelImpressions());
                        createChannelImpressionsWithThresholds());
                if (ranking.getImportance() > IMPORTANCE_MIN && ci.shouldTriggerBlock()) {
                    adjustNotification(createNegativeAdjustment(
                            sbn.getPackageName(), sbn.getKey(), sbn.getUserId()));
@@ -206,7 +221,7 @@ public class Assistant extends NotificationAssistantService {
            String key = getKey(sbn.getPackageName(), sbn.getUserId(), channelId);
            synchronized (mkeyToImpressions) {
                ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
                        new ChannelImpressions());
                        createChannelImpressionsWithThresholds());
                if (stats.hasSeen()) {
                    ci.incrementViews();
                    updatedImpressions = true;
@@ -310,4 +325,58 @@ public class Assistant extends NotificationAssistantService {
            mkeyToImpressions.put(key, ci);
        }
    }

    private ChannelImpressions createChannelImpressionsWithThresholds() {
        ChannelImpressions impressions = new ChannelImpressions();
        impressions.updateThresholds(mDismissToViewRatioLimit, mStreakLimit);
        return impressions;
    }

    /**
     * Observer for updates on blocking helper threshold values.
     */
    private final class SettingsObserver extends ContentObserver {
        private final Uri STREAK_LIMIT_URI =
                Settings.Global.getUriFor(Settings.Global.BLOCKING_HELPER_STREAK_LIMIT);
        private final Uri DISMISS_TO_VIEW_RATIO_LIMIT_URI =
                Settings.Global.getUriFor(
                        Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT);

        public SettingsObserver(Handler handler) {
            super(handler);
            ContentResolver resolver = getApplicationContext().getContentResolver();
            resolver.registerContentObserver(
                    DISMISS_TO_VIEW_RATIO_LIMIT_URI, false, this, getUserId());
            resolver.registerContentObserver(STREAK_LIMIT_URI, false, this, getUserId());

            // Update all uris on creation.
            update(null);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            update(uri);
        }

        private void update(Uri uri) {
            ContentResolver resolver = getApplicationContext().getContentResolver();
            if (uri == null || DISMISS_TO_VIEW_RATIO_LIMIT_URI.equals(uri)) {
                mDismissToViewRatioLimit = Settings.Global.getFloat(
                        resolver, Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
                        ChannelImpressions.DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT);
            }
            if (uri == null || STREAK_LIMIT_URI.equals(uri)) {
                mStreakLimit = Settings.Global.getInt(
                        resolver, Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
                        ChannelImpressions.DEFAULT_STREAK_LIMIT);
            }

            // Update all existing channel impression objects with any new limits/thresholds.
            synchronized (mkeyToImpressions) {
                for (ChannelImpressions channelImpressions: mkeyToImpressions.values()) {
                    channelImpressions.updateThresholds(mDismissToViewRatioLimit, mStreakLimit);
                }
            }
        }
    }
}
 No newline at end of file
+33 −10
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

@@ -30,8 +32,8 @@ public final class ChannelImpressions implements Parcelable {
    private static final String TAG = "ExtAssistant.CI";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    static final double DISMISS_TO_VIEW_RATIO_LIMIT = .4;
    static final int STREAK_LIMIT = 2;
    static final float DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT = .4f;
    static final int DEFAULT_STREAK_LIMIT = 2;
    static final String ATT_DISMISSALS = "dismisses";
    static final String ATT_VIEWS = "views";
    static final String ATT_STREAK = "streak";
@@ -40,18 +42,20 @@ public final class ChannelImpressions implements Parcelable {
    private int mViews = 0;
    private int mStreak = 0;

    public ChannelImpressions() {
    }
    private float mDismissToViewRatioLimit;
    private int mStreakLimit;

    public ChannelImpressions(int dismissals, int views) {
        mDismissals = dismissals;
        mViews = views;
    public ChannelImpressions() {
        mDismissToViewRatioLimit = DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT;
        mStreakLimit = DEFAULT_STREAK_LIMIT;
    }

    protected ChannelImpressions(Parcel in) {
        mDismissals = in.readInt();
        mViews = in.readInt();
        mStreak = in.readInt();
        mDismissToViewRatioLimit = in.readFloat();
        mStreakLimit = in.readInt();
    }

    public int getStreak() {
@@ -71,6 +75,21 @@ public final class ChannelImpressions implements Parcelable {
        mStreak++;
    }

    void updateThresholds(float dismissToViewRatioLimit, int streakLimit) {
        mDismissToViewRatioLimit = dismissToViewRatioLimit;
        mStreakLimit = streakLimit;
    }

    @VisibleForTesting
    float getDismissToViewRatioLimit() {
        return mDismissToViewRatioLimit;
    }

    @VisibleForTesting
    int getStreakLimit() {
        return mStreakLimit;
    }

    public void append(ChannelImpressions additionalImpressions) {
        if (additionalImpressions != null) {
            mViews += additionalImpressions.getViews();
@@ -94,8 +113,8 @@ public final class ChannelImpressions implements Parcelable {
        if (DEBUG) {
            Log.d(TAG, "should trigger? " + getDismissals() + " " + getViews() + " " + getStreak());
        }
        return ((double) getDismissals() / getViews()) > DISMISS_TO_VIEW_RATIO_LIMIT
                && getStreak() > STREAK_LIMIT;
        return ((float) getDismissals() / getViews()) > mDismissToViewRatioLimit
                && getStreak() > mStreakLimit;
    }

    @Override
@@ -103,6 +122,8 @@ public final class ChannelImpressions implements Parcelable {
        dest.writeInt(mDismissals);
        dest.writeInt(mViews);
        dest.writeInt(mStreak);
        dest.writeFloat(mDismissToViewRatioLimit);
        dest.writeInt(mStreakLimit);
    }

    @Override
@@ -148,7 +169,9 @@ public final class ChannelImpressions implements Parcelable {
        sb.append("mDismissals=").append(mDismissals);
        sb.append(", mViews=").append(mViews);
        sb.append(", mStreak=").append(mStreak);
        sb.append('}');
        sb.append(", thresholds=(").append(mDismissToViewRatioLimit);
        sb.append(",").append(mStreakLimit);
        sb.append(")}");
        return sb.toString();
    }

Loading