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

Commit 6f57f2c2 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Notification app screen updates

- Load channels asynchronously
- Add importance summary & block/unblock toggle for channel list
- Change channel list headers and sorting.

Test: manual
Change-Id: If024c741df4d85227055563d5bbc8210705c420b
parent aa6e4b5b
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -6372,7 +6372,10 @@
    <string name="loading_notification_apps">Loading apps...</string>
    <!-- [CHAR LIMIT=NONE] App notification settings: channels title -->
    <string name="notification_channels">Channels</string>
    <string name="notification_channels">Categories</string>
    <!-- [CHAR LIMIT=NONE] App notification settings: non-grouped-channels title -->
    <string name="notification_channels_other">Other</string>
    <!-- [CHAR LIMIT=NONE] App notification settings: no channels -->
    <string name="no_channels">This app has not posted any notifications</string>
+0 −4
Original line number Diff line number Diff line
@@ -34,8 +34,4 @@
        settings:useAdditionalSummary="true"
        settings:restrictedSwitchSummary="@string/enabled_by_admin" />

    <PreferenceCategory
            android:key="channels"
            android:title="@string/notification_channels" />

</PreferenceScreen>
+100 −57
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.settings.notification;

import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -24,6 +27,7 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.preference.Preference;
@@ -41,10 +45,12 @@ import com.android.settings.applications.AppInfoBase;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.notification.NotificationBackend.AppRow;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.MasterSwitchPreference;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.RestrictedSwitchPreference;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -63,8 +69,8 @@ public class AppNotificationSettings extends NotificationSettingsBase {
    private static final String KEY_BLOCK = "block";

    private DashboardFeatureProvider mDashboardFeatureProvider;
    private PreferenceCategory mChannels;
    private List<NotificationChannelGroup> mChannelGroupList;
    private List<PreferenceCategory> mChannelGroups = new ArrayList();

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
@@ -98,7 +104,6 @@ public class AppNotificationSettings extends NotificationSettingsBase {

        mBlock = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BLOCK);
        mBadge = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BADGE);
        mChannels = (PreferenceCategory) findPreference(KEY_CHANNELS);

        if (mPkgInfo != null) {
            setupBlock();
@@ -107,41 +112,90 @@ public class AppNotificationSettings extends NotificationSettingsBase {
            ArrayMap<String, AppRow> rows = new ArrayMap<String, AppRow>();
            rows.put(mAppRow.pkg, mAppRow);
            collectConfigActivities(rows);
            // TODO: load channels in asynctask?
            new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(Void... unused) {
                    mChannelGroupList = mBackend.getChannelGroups(mPkg, mUid).getList();
                    Collections.sort(mChannelGroupList, mChannelGroupComparator);
                    return null;
                }

                @Override
                protected void onPostExecute(Void unused) {
                    populateChannelList();
                }
            }.execute();
        }
        if (mDashboardFeatureProvider.isEnabled()) {
            final Preference pref = FeatureFactory.getFactory(activity)
                    .getApplicationFeatureProvider(activity)
                    .newAppHeaderController(this /* fragment */, null /* appHeader */)
                    .setIcon(mAppRow.icon)
                    .setLabel(mAppRow.label)
                    .setPackageName(mAppRow.pkg)
                    .setUid(mAppRow.uid)
                    .setAppNotifPrefIntent(mAppRow.settingsIntent)
                    .setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO,
                            AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE)
                    .done(getPrefContext());
            getPreferenceScreen().addPreference(pref);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
            Log.w(TAG, "Missing package or uid or packageinfo");
            finish();
            return;
        }
    }

    private void populateChannelList() {
        if (mChannelGroupList.isEmpty()) {
            PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
            groupCategory.setTitle(R.string.notification_channels);
            getPreferenceScreen().addPreference(groupCategory);
            mChannelGroups.add(groupCategory);

            Preference empty = new Preference(getPrefContext());
            empty.setTitle(R.string.no_channels);
            empty.setEnabled(false);
                mChannels.addPreference(empty);
            groupCategory.addPreference(empty);
        } else {
            for (NotificationChannelGroup group : mChannelGroupList) {
                    PreferenceCategory groupCategory = null;
                    if (group.getId() != null && group.getName() != null) {
                        groupCategory = new PreferenceCategory(getPrefContext());
                PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
                if (group.getName() == null) {
                    groupCategory.setTitle(mChannelGroupList.size() > 1
                            ? R.string.notification_channels_other
                            : R.string.notification_channels);
                } else {
                    groupCategory.setTitle(group.getName());
                }
                groupCategory.setKey(group.getId());
                groupCategory.setOrderingAsAdded(true);
                getPreferenceScreen().addPreference(groupCategory);
                    }
                mChannelGroups.add(groupCategory);

                final List<NotificationChannel> channels = group.getChannels();
                Collections.sort(channels, mChannelComparator);
                int N = channels.size();
                for (int i = 0; i < N; i++) {
                    final NotificationChannel channel = channels.get(i);
                        RestrictedPreference channelPref = new RestrictedPreference(
                    MasterSwitchPreference channelPref = new MasterSwitchPreference(
                            getPrefContext());
                    channelPref.setDisabledByAdmin(mSuspendedAppsAdmin);
                    channelPref.setKey(channel.getId());
                    channelPref.setTitle(channel.getName());
                    channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE);

                    if (channel.isDeleted()) {
                        channelPref.setTitle(
                                getString(R.string.deleted_channel_name, channel.getName()));
                        channelPref.setEnabled(false);
                    } else {
                        channelPref.setSummary(getImportanceSummary(channel.getImportance()));
                        Bundle channelArgs = new Bundle();
                        channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
                        channelArgs.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true);
@@ -151,42 +205,29 @@ public class AppNotificationSettings extends NotificationSettingsBase {
                                ChannelNotificationSettings.class.getName(),
                                channelArgs, null, 0, null, false);
                        channelPref.setIntent(channelIntent);

                        channelPref.setOnPreferenceChangeListener(
                                new Preference.OnPreferenceChangeListener() {
                                    @Override
                                    public boolean onPreferenceChange(Preference preference,
                                            Object o) {
                                        boolean value = (Boolean) o;
                                        int importance = value ?  IMPORTANCE_LOW : IMPORTANCE_NONE;
                                        channel.setImportance(importance);
                                        channel.lockFields(
                                                NotificationChannel.USER_LOCKED_IMPORTANCE);
                                        mBackend.updateChannel(mPkg, mUid, channel);

                                        return true;
                                    }
                        if (groupCategory != null) {
                            groupCategory.addPreference(channelPref);
                        } else {
                            mChannels.addPreference(channelPref);
                                });
                    }
                    groupCategory.addPreference(channelPref);
                }
            }
        }
        updateDependents(mAppRow.banned);
    }
        if (mDashboardFeatureProvider.isEnabled()) {
            final Preference pref = FeatureFactory.getFactory(activity)
                    .getApplicationFeatureProvider(activity)
                    .newAppHeaderController(this /* fragment */, null /* appHeader */)
                    .setIcon(mAppRow.icon)
                    .setLabel(mAppRow.label)
                    .setPackageName(mAppRow.pkg)
                    .setUid(mAppRow.uid)
                    .setAppNotifPrefIntent(mAppRow.settingsIntent)
                    .setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO,
                            AppHeaderController.ActionType.ACTION_NOTIF_PREFERENCE)
                    .done(getPrefContext());
            getPreferenceScreen().addPreference(pref);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
            Log.w(TAG, "Missing package or uid or packageinfo");
            finish();
            return;
        }
    }

    private void setupBadge() {
        mBadge.setDisabledByAdmin(mSuspendedAppsAdmin);
@@ -223,7 +264,9 @@ public class AppNotificationSettings extends NotificationSettingsBase {
    }

    private void updateDependents(boolean banned) {
        setVisible(mChannels, !banned);
        for (PreferenceCategory category : mChannelGroups) {
            setVisible(category, !banned);
        }
        setVisible(mBadge, !banned);
    }

@@ -289,7 +332,7 @@ public class AppNotificationSettings extends NotificationSettingsBase {

                @Override
                public int compare(NotificationChannelGroup left, NotificationChannelGroup right) {
                    // Non-groups channels (in placeholder group with a null id) come first
                    // Non-grouped channels (in placeholder group with a null id) come last
                    if (left.getId() == null && right.getId() != null) {
                        return 1;
                    } else if (right.getId() == null && left.getId() != null) {
+2 −21
Original line number Diff line number Diff line
@@ -230,12 +230,12 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
        List<String> values = new ArrayList<>();;
        for (int i = 0; i < numImportances; i++) {
            int importance = i + 1;
            summaries.add(getSummary(importance));
            summaries.add(getImportanceSummary(importance));
            values.add(String.valueOf(importance));
        }
        if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())) {
            // Add option to reset to letting the app decide
            summaries.add(getSummary(NotificationManager.IMPORTANCE_UNSPECIFIED));
            summaries.add(getImportanceSummary(NotificationManager.IMPORTANCE_UNSPECIFIED));
            values.add(String.valueOf(NotificationManager.IMPORTANCE_UNSPECIFIED));
        }
        mImportance.setEntryValues(values.toArray(new String[0]));
@@ -256,25 +256,6 @@ public class ChannelNotificationSettings extends NotificationSettingsBase {
        });
    }

    private String getSummary(int importance) {
        switch (importance) {
            case NotificationManager.IMPORTANCE_UNSPECIFIED:
                return getContext().getString(R.string.notification_importance_unspecified);
            case NotificationManager.IMPORTANCE_NONE:
                return getContext().getString(R.string.notification_importance_blocked);
            case NotificationManager.IMPORTANCE_MIN:
                return getContext().getString(R.string.notification_importance_min);
            case NotificationManager.IMPORTANCE_LOW:
                return getContext().getString(R.string.notification_importance_low);
            case NotificationManager.IMPORTANCE_DEFAULT:
                return getContext().getString(R.string.notification_importance_default);
            case NotificationManager.IMPORTANCE_HIGH:
            case NotificationManager.IMPORTANCE_MAX:
            default:
                return getContext().getString(R.string.notification_importance_high);
        }
    }

    protected void setupPriorityPref(boolean priority) {
        mPriority.setDisabledByAdmin(mSuspendedAppsAdmin);
        mPriority.setChecked(priority);
+16 −9
Original line number Diff line number Diff line
@@ -176,15 +176,22 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen
        return null;
    }

    private PackageInfo findPackageInfo(String pkg) {
        if (pkg == null) {
            return null;
    protected String getImportanceSummary(int importance) {
        switch (importance) {
            case NotificationManager.IMPORTANCE_UNSPECIFIED:
                return getContext().getString(R.string.notification_importance_unspecified);
            case NotificationManager.IMPORTANCE_NONE:
                return getContext().getString(R.string.notification_importance_blocked);
            case NotificationManager.IMPORTANCE_MIN:
                return getContext().getString(R.string.notification_importance_min);
            case NotificationManager.IMPORTANCE_LOW:
                return getContext().getString(R.string.notification_importance_low);
            case NotificationManager.IMPORTANCE_DEFAULT:
                return getContext().getString(R.string.notification_importance_default);
            case NotificationManager.IMPORTANCE_HIGH:
            case NotificationManager.IMPORTANCE_MAX:
            default:
                return getContext().getString(R.string.notification_importance_high);
        }
        try {
            return mPm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
        } catch (NameNotFoundException e) {
            Log.w(TAG, "Failed to load package " + pkg, e);
        }
        return null;
    }
}