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

Commit 24cfa9d4 authored by Yuri Lin's avatar Yuri Lin
Browse files

Change Settings controllers & pages to for per-user bundle settings

This change maintains existing UI and does not (yet) add new settings to actually adjust the preferences for managed profiles; but the existing switches as well as relevant NotificationBackend methods are updated to have the correct functionality for what they're meant to do.

Flag: android.app.notification_classification_ui
Bug: 380290891
Test: AdjustmentExcludedAppsPreferenceControllerTest, BundleCombinedPreferenceControllerTest, SummarizationGlobalPreferenceControllerTest, SummarizationPreferenceControllerTest, AdjustmentKeyPreferenceControllerTest, BundlePreferenceControllerTest

Change-Id: I23e8f3fd81414b8783aa3a9262f9d4bb57ad0287
parent 2088cc10
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -22,7 +22,10 @@ import static android.service.notification.Adjustment.KEY_TYPE;
import android.app.Flags;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.notification.Adjustment;
import android.util.ArrayMap;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -42,7 +45,9 @@ import com.android.settingslib.utils.ThreadUtils;
import com.google.common.util.concurrent.ListenableFuture;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Adds a preference to the PreferenceCategory for every app excluded from an adjustment key
@@ -58,11 +63,18 @@ public class AdjustmentExcludedAppsPreferenceController extends BasePreferenceCo
    @VisibleForTesting Context mPrefContext;

    private ApplicationsState.Session mAppSession;
    private UserManager mUserManager;

    public AdjustmentExcludedAppsPreferenceController(@NonNull Context context,
            @NonNull String preferenceKey) {
        super(context, preferenceKey);
        mBackend = new NotificationBackend();
        mUserManager = context.getSystemService(UserManager.class);
    }

    @VisibleForTesting
    void setUserManager(UserManager um) {
        mUserManager = um;
    }

    protected void onAttach(@Nullable ApplicationsState appState, @Nullable Fragment host,
@@ -135,18 +147,24 @@ public class AdjustmentExcludedAppsPreferenceController extends BasePreferenceCo

    @VisibleForTesting
    void updateAppList(List<ApplicationsState.AppEntry> apps) {
        if (mPreferenceCategory == null || apps == null) {
        if (mPreferenceCategory == null || mAdjustmentKey == null || apps == null) {
            return;
        }

        List<String> excludedApps = mBackend.getAdjustmentDeniedPackages(mAdjustmentKey);
        Map<Integer, List<String>> excludedAppsByUser = new ArrayMap<>();
        for (UserHandle userHandle : mUserManager.getUserProfiles()) {
            int userId = userHandle.getIdentifier();
            excludedAppsByUser.put(userId,
                    mBackend.getAdjustmentDeniedPackages(userId, mAdjustmentKey));
        }

        for (ApplicationsState.AppEntry app : apps) {
            String pkg = app.info.packageName;
            int userId = UserHandle.getUserId(app.info.uid);
            final String key = getKey(pkg, app.info.uid);
            boolean doesAppPassCriteria = false;

            if (excludedApps.contains(pkg)) {
            if (excludedAppsByUser.getOrDefault(userId, Collections.EMPTY_LIST).contains(pkg)) {
                doesAppPassCriteria = true;
            }
            Preference pref = mPreferenceCategory.findPreference(key);
+4 −3
Original line number Diff line number Diff line
@@ -87,13 +87,14 @@ public class BundleCombinedPreferenceController extends BasePreferenceController
    }

    void updatePrefValues() {
        boolean isBundlingEnabled = mBackend.isNotificationBundlingEnabled(mContext);
        // TODO: b/412433475 - update for profile users (add a work profile switch).
        boolean isBundlingEnabled = mBackend.isNotificationBundlingEnabled(mContext.getUserId());
        Set<Integer> allowedTypes = mBackend.getAllowedBundleTypes();

        // State check: if bundling is globally enabled, but there are no allowed bundle types,
        // disable the global bundling state from here before proceeding.
        if (isBundlingEnabled && allowedTypes.size() == 0) {
            mBackend.setNotificationBundlingEnabled(false);
            mBackend.setNotificationBundlingEnabled(mContext.getUserId(), false);
            isBundlingEnabled = false;
        }

@@ -113,7 +114,7 @@ public class BundleCombinedPreferenceController extends BasePreferenceController

    private Preference.OnPreferenceChangeListener mGlobalPrefListener = (p, val) -> {
        boolean checked = (boolean) val;
        mBackend.setNotificationBundlingEnabled(checked);
        mBackend.setNotificationBundlingEnabled(mContext.getUserId(), checked);
        // update state to hide or show preferences for individual types
        updatePrefValues();
        return true;
+28 −17
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER;

import android.annotation.FlaggedApi;
import android.annotation.UserIdInt;
import android.app.Flags;
import android.app.INotificationManager;
import android.app.NotificationChannel;
@@ -682,9 +683,9 @@ public class NotificationBackend {
        return false;
    }

    public boolean isNotificationBundlingEnabled(Context context) {
    public boolean isNotificationBundlingEnabled(@UserIdInt int userId) {
        try {
            return sINM.getAllowedAssistantAdjustments(context.getPackageName())
            return sINM.getAllowedAssistantAdjustmentsForUser(userId)
                    .contains(Adjustment.KEY_TYPE);
        } catch (Exception e) {
            Log.w(TAG, "Error calling NoMan", e);
@@ -692,12 +693,12 @@ public class NotificationBackend {
        return false;
    }

    public void setNotificationBundlingEnabled(boolean enabled) {
    public void setNotificationBundlingEnabled(@UserIdInt int userId, boolean enabled) {
        try {
            if (enabled) {
                sINM.allowAssistantAdjustment(Adjustment.KEY_TYPE);
                sINM.allowAssistantAdjustment(userId, Adjustment.KEY_TYPE);
            } else {
                sINM.disallowAssistantAdjustment(Adjustment.KEY_TYPE);
                sINM.disallowAssistantAdjustment(userId, Adjustment.KEY_TYPE);
            }
        } catch (Exception e) {
            Log.w(TAG, "Error calling NoMan", e);
@@ -713,9 +714,9 @@ public class NotificationBackend {
        return false;
    }

    public boolean isNotificationSummarizationEnabled(Context context) {
    public boolean isNotificationSummarizationEnabled(@UserIdInt int userId) {
        try {
            return sINM.getAllowedAssistantAdjustments(context.getPackageName())
            return sINM.getAllowedAssistantAdjustmentsForUser(userId)
                    .contains(Adjustment.KEY_SUMMARIZATION);
        } catch (Exception e) {
            Log.w(TAG, "Error calling NoMan", e);
@@ -723,12 +724,12 @@ public class NotificationBackend {
        return false;
    }

    public void setNotificationSummarizationEnabled(boolean enabled) {
    public void setNotificationSummarizationEnabled(@UserIdInt int userId, boolean enabled) {
        try {
            if (enabled) {
                sINM.allowAssistantAdjustment(Adjustment.KEY_SUMMARIZATION);
                sINM.allowAssistantAdjustment(userId, Adjustment.KEY_SUMMARIZATION);
            } else {
                sINM.disallowAssistantAdjustment(Adjustment.KEY_SUMMARIZATION);
                sINM.disallowAssistantAdjustment(userId, Adjustment.KEY_SUMMARIZATION);
            }
        } catch (Exception e) {
            Log.w(TAG, "Error calling NoMan", e);
@@ -737,7 +738,7 @@ public class NotificationBackend {

    public boolean isBundleTypeApproved(@Adjustment.Types int type) {
        try {
            int[] approved = sINM.getAllowedAdjustmentKeyTypes();
            int[] approved = sINM.getAllowedClassificationTypes();
            for (int approvedType : approved) {
                if (type == approvedType) {
                    return true;
@@ -752,7 +753,7 @@ public class NotificationBackend {
    public Set<Integer> getAllowedBundleTypes() {
        try {
            Set<Integer> allowed = new HashSet<>();
            for (int type : sINM.getAllowedAdjustmentKeyTypes()) {
            for (int type : sINM.getAllowedClassificationTypes()) {
                allowed.add(type);
            }
            return allowed;
@@ -764,7 +765,7 @@ public class NotificationBackend {

    public void setBundleTypeState(@Adjustment.Types int type, boolean enabled) {
        try {
            sINM.setAssistantAdjustmentKeyTypeState(type, enabled);
            sINM.setAssistantClassificationTypeState(type, enabled);
        } catch (Exception e) {
            Log.w(TAG, "Error calling NoMan", e);
        }
@@ -799,18 +800,28 @@ public class NotificationBackend {
        }
    }

    public @NonNull List<String> getAdjustmentDeniedPackages(String key) {
    public @NonNull List<String> getAdjustmentDeniedPackages(@UserIdInt int userId, String key) {
        try {
            return List.of(sINM.getAdjustmentDeniedPackages(key));
            return List.of(sINM.getAdjustmentDeniedPackages(userId, key));
        } catch (Exception e) {
            Log.w(TAG, "Error calling NoMan", e);
            return new ArrayList<>();
        }
    }

    public @NonNull void setAdjustmentSupportedForPackage(String key, String pkg, boolean enabled) {
    public boolean isAdjustmentSupportedForPackage(@UserIdInt int userId, String key, String pkg) {
        try {
            sINM.setAdjustmentSupportedForPackage(key, pkg, enabled);
            return sINM.isAdjustmentSupportedForPackage(userId, key, pkg);
        } catch (Exception e) {
            Log.w(TAG, "Error calling NoMan", e);
            return false;
        }
    }

    public void setAdjustmentSupportedForPackage(@UserIdInt int userId, String key, String pkg,
            boolean enabled) {
        try {
            sINM.setAdjustmentSupportedForPackage(userId, key, pkg, enabled);
        } catch (Exception e) {
            Log.w(TAG, "Error calling NoMan", e);
        }
+2 −2
Original line number Diff line number Diff line
@@ -44,12 +44,12 @@ public class SummarizationGlobalPreferenceController extends TogglePreferenceCon

    @Override
    public boolean isChecked() {
        return mBackend.isNotificationSummarizationEnabled(mContext);
        return mBackend.isNotificationSummarizationEnabled(mContext.getUserId());
    }

    @Override
    public boolean setChecked(boolean isChecked) {
        mBackend.setNotificationSummarizationEnabled(isChecked);
        mBackend.setNotificationSummarizationEnabled(mContext.getUserId(), isChecked);
        return true;
    }

+3 −2
Original line number Diff line number Diff line
@@ -89,7 +89,8 @@ public class AdjustmentKeyPreferenceController extends
        if (pref != null && mAppRow != null) {
            pref.setDisabledByAdmin(mAdmin);
            pref.setEnabled(!pref.isDisabledByAdmin());
            pref.setChecked(!mBackend.getAdjustmentDeniedPackages(mKey).contains(mAppRow.pkg));
            pref.setChecked(
                    mBackend.isAdjustmentSupportedForPackage(mAppRow.userId, mKey, mAppRow.pkg));
            pref.setOnPreferenceChangeListener(this);
        }
    }
@@ -97,7 +98,7 @@ public class AdjustmentKeyPreferenceController extends
    @Override
    public boolean onPreferenceChange(@NonNull Preference preference, @NonNull Object newValue) {
        final boolean allowedForPkg = (Boolean) newValue;
        mBackend.setAdjustmentSupportedForPackage(mKey, mAppRow.pkg, allowedForPkg);
        mBackend.setAdjustmentSupportedForPackage(mAppRow.userId, mKey, mAppRow.pkg, allowedForPkg);
        return true;
    }
}
Loading