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

Commit 566a0093 authored by Rohan Shah's avatar Rohan Shah Committed by android-build-merger
Browse files

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

am: 7af8fe3e

Change-Id: I5a5307d2345bb4ab5d3e91f3b58eaf8fc875f1ef
parents 04621f5b 7af8fe3e
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -12578,6 +12578,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
@@ -132,6 +132,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