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

Commit 26f79f9c authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Add APIs for notification app overlays"

parents 68585439 b6bd93d9
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -5217,6 +5217,7 @@ package android.app {
    ctor public Notification(android.os.Parcel);
    method public android.app.Notification clone();
    method public int describeContents();
    method public android.app.PendingIntent getAppOverlayIntent();
    method public int getBadgeIconType();
    method public java.lang.String getChannelId();
    method public java.lang.String getGroup();
@@ -5446,6 +5447,7 @@ package android.app {
    method public android.app.Notification.Style getStyle();
    method public static android.app.Notification.Builder recoverBuilder(android.content.Context, android.app.Notification);
    method public android.app.Notification.Builder setActions(android.app.Notification.Action...);
    method public android.app.Notification.Builder setAppOverlayIntent(android.app.PendingIntent);
    method public android.app.Notification.Builder setAutoCancel(boolean);
    method public android.app.Notification.Builder setBadgeIconType(int);
    method public android.app.Notification.Builder setCategory(java.lang.String);
@@ -5663,6 +5665,7 @@ package android.app {
  public final class NotificationChannel implements android.os.Parcelable {
    ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
    method public boolean canBypassDnd();
    method public boolean canOverlayApps();
    method public boolean canShowBadge();
    method public int describeContents();
    method public void enableLights(boolean);
@@ -5678,6 +5681,7 @@ package android.app {
    method public android.net.Uri getSound();
    method public long[] getVibrationPattern();
    method public boolean hasUserSetImportance();
    method public void setAllowAppOverlay(boolean);
    method public void setBypassDnd(boolean);
    method public void setDescription(java.lang.String);
    method public void setGroup(java.lang.String);
@@ -5697,6 +5701,7 @@ package android.app {
  public final class NotificationChannelGroup implements android.os.Parcelable {
    ctor public NotificationChannelGroup(java.lang.String, java.lang.CharSequence);
    method public boolean canOverlayApps();
    method public android.app.NotificationChannelGroup clone();
    method public int describeContents();
    method public java.util.List<android.app.NotificationChannel> getChannels();
@@ -5704,6 +5709,7 @@ package android.app {
    method public java.lang.String getId();
    method public java.lang.CharSequence getName();
    method public boolean isBlocked();
    method public void setAllowAppOverlay(boolean);
    method public void setDescription(java.lang.String);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.app.NotificationChannelGroup> CREATOR;
+3 −0
Original line number Diff line number Diff line
@@ -140,7 +140,10 @@ package android.app {
  }

  public final class NotificationChannelGroup implements android.os.Parcelable {
    method public int getUserLockedFields();
    method public void lockFields(int);
    method public void setBlocked(boolean);
    field public static final int USER_LOCKED_ALLOW_APP_OVERLAY = 2; // 0x2
  }

  public class NotificationManager {
+38 −0
Original line number Diff line number Diff line
@@ -1275,6 +1275,8 @@ public class Notification implements Parcelable
    private String mShortcutId;
    private CharSequence mSettingsText;

    private PendingIntent mAppOverlayIntent;

    /** @hide */
    @IntDef(prefix = { "GROUP_ALERT_" }, value = {
            GROUP_ALERT_ALL, GROUP_ALERT_CHILDREN, GROUP_ALERT_SUMMARY
@@ -2225,6 +2227,9 @@ public class Notification implements Parcelable
        }

        mGroupAlertBehavior = parcel.readInt();
        if (parcel.readInt() != 0) {
            mAppOverlayIntent = PendingIntent.CREATOR.createFromParcel(parcel);
        }
    }

    @Override
@@ -2339,6 +2344,7 @@ public class Notification implements Parcelable
        that.mBadgeIcon = this.mBadgeIcon;
        that.mSettingsText = this.mSettingsText;
        that.mGroupAlertBehavior = this.mGroupAlertBehavior;
        that.mAppOverlayIntent = this.mAppOverlayIntent;

        if (!heavy) {
            that.lightenPayload(); // will clean out extras
@@ -2660,6 +2666,13 @@ public class Notification implements Parcelable

        parcel.writeInt(mGroupAlertBehavior);

        if (mAppOverlayIntent != null) {
            parcel.writeInt(1);
            mAppOverlayIntent.writeToParcel(parcel, 0);
        } else {
            parcel.writeInt(0);
        }

        // mUsesStandardHeader is not written because it should be recomputed in listeners
    }

@@ -3072,6 +3085,14 @@ public class Notification implements Parcelable
        return mGroupAlertBehavior;
    }

    /**
     * Returns the intent that will be used to display app content in a floating window over the
     * existing foreground activity.
     */
    public PendingIntent getAppOverlayIntent() {
        return mAppOverlayIntent;
    }

    /**
     * The small icon representing this notification in the status bar and content view.
     *
@@ -3406,6 +3427,23 @@ public class Notification implements Parcelable
            return this;
        }

        /**
         * Sets the intent that will be used to display app content in a floating window
         * over the existing foreground activity.
         *
         * <p>This intent will be ignored unless this notification is posted to a channel that
         * allows {@link NotificationChannel#canOverlayApps() app overlays}.</p>
         *
         * <p>Notifications with a valid and allowed app overlay intent will be displayed as
         * floating windows outside of the notification shade on unlocked devices. When a user
         * interacts with one of these windows, this app overlay intent will be invoked and
         * displayed.</p>
         */
        public Builder setAppOverlayIntent(PendingIntent intent) {
            mN.mAppOverlayIntent = intent;
            return this;
        }

        /** @removed */
        @Deprecated
        public Builder setChannel(String channelId) {
+79 −46
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package android.app;

import static android.app.NotificationManager.IMPORTANCE_HIGH;

import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
@@ -41,6 +43,7 @@ import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Objects;

/**
 * A representation of settings that apply to a collection of similarly themed notifications.
@@ -81,6 +84,7 @@ public final class NotificationChannel implements Parcelable {
    private static final String ATT_FG_SERVICE_SHOWN = "fgservice";
    private static final String ATT_GROUP = "group";
    private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system";
    private static final String ATT_ALLOW_APP_OVERLAY = "app_overlay";
    private static final String DELIMITER = ",";

    /**
@@ -113,6 +117,11 @@ public final class NotificationChannel implements Parcelable {
     */
    public static final int USER_LOCKED_SHOW_BADGE = 0x00000080;

    /**
     * @hide
     */
    public static final int USER_LOCKED_ALLOW_APP_OVERLAY = 0x00000100;

    /**
     * @hide
     */
@@ -124,6 +133,7 @@ public final class NotificationChannel implements Parcelable {
            USER_LOCKED_VIBRATION,
            USER_LOCKED_SOUND,
            USER_LOCKED_SHOW_BADGE,
            USER_LOCKED_ALLOW_APP_OVERLAY
    };

    private static final int DEFAULT_LIGHT_COLOR = 0;
@@ -133,6 +143,7 @@ public final class NotificationChannel implements Parcelable {
            NotificationManager.IMPORTANCE_UNSPECIFIED;
    private static final boolean DEFAULT_DELETED = false;
    private static final boolean DEFAULT_SHOW_BADGE = true;
    private static final boolean DEFAULT_ALLOW_APP_OVERLAY = true;

    @UnsupportedAppUsage
    private final String mId;
@@ -156,6 +167,7 @@ public final class NotificationChannel implements Parcelable {
    private AudioAttributes mAudioAttributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
    // If this is a blockable system notification channel.
    private boolean mBlockableSystem = false;
    private boolean mAllowAppOverlay = DEFAULT_ALLOW_APP_OVERLAY;

    /**
     * Creates a notification channel.
@@ -217,6 +229,7 @@ public final class NotificationChannel implements Parcelable {
        mAudioAttributes = in.readInt() > 0 ? AudioAttributes.CREATOR.createFromParcel(in) : null;
        mLightColor = in.readInt();
        mBlockableSystem = in.readBoolean();
        mAllowAppOverlay = in.readBoolean();
    }

    @Override
@@ -269,6 +282,7 @@ public final class NotificationChannel implements Parcelable {
        }
        dest.writeInt(mLightColor);
        dest.writeBoolean(mBlockableSystem);
        dest.writeBoolean(mAllowAppOverlay);
    }

    /**
@@ -460,6 +474,22 @@ public final class NotificationChannel implements Parcelable {
        this.mLockscreenVisibility = lockscreenVisibility;
    }

    /**
     * Sets whether notifications posted to this channel can appear outside of the notification
     * shade, floating over other apps' content.
     *
     * <p>This value will be ignored for channels that aren't allowed to pop on screen (that is,
     * channels whose {@link #getImportance() importance} is <
     * {@link NotificationManager#IMPORTANCE_HIGH}.</p>
     *
     * <p>Only modifiable before the channel is submitted to
     *      * {@link NotificationManager#createNotificationChannel(NotificationChannel)}.</p>
     * @see Notification#getAppOverlayIntent()
     */
    public void setAllowAppOverlay(boolean allowAppOverlay) {
        mAllowAppOverlay = allowAppOverlay;
    }

    /**
     * Returns the id of this channel.
     */
@@ -572,6 +602,22 @@ public final class NotificationChannel implements Parcelable {
        return mGroup;
    }

    /**
     * Returns whether notifications posted to this channel can display outside of the notification
     * shade, in a floating window on top of other apps.
     */
    public boolean canOverlayApps() {
        return isAppOverlayAllowed() && getImportance() >= IMPORTANCE_HIGH;
    }

    /**
     * Like {@link #canOverlayApps()}, but only checks the permission, not the importance.
     * @hide
     */
    public boolean isAppOverlayAllowed() {
        return mAllowAppOverlay;
    }

    /**
     * @hide
     */
@@ -605,6 +651,7 @@ public final class NotificationChannel implements Parcelable {
    /**
     * Returns whether the user has chosen the importance of this channel, either to affirm the
     * initial selection from the app, or changed it to be higher or lower.
     * @see #getImportance()
     */
    public boolean hasUserSetImportance() {
        return (mUserLockedFields & USER_LOCKED_IMPORTANCE) != 0;
@@ -652,6 +699,7 @@ public final class NotificationChannel implements Parcelable {
        lockFields(safeInt(parser, ATT_USER_LOCKED, 0));
        setFgServiceShown(safeBool(parser, ATT_FG_SERVICE_SHOWN, false));
        setBlockableSystem(safeBool(parser, ATT_BLOCKABLE_SYSTEM, false));
        setAllowAppOverlay(safeBool(parser, ATT_ALLOW_APP_OVERLAY, DEFAULT_ALLOW_APP_OVERLAY));
    }

    @Nullable
@@ -770,6 +818,9 @@ public final class NotificationChannel implements Parcelable {
        if (isBlockableSystem()) {
            out.attribute(null, ATT_BLOCKABLE_SYSTEM, Boolean.toString(isBlockableSystem()));
        }
        if (canOverlayApps() != DEFAULT_ALLOW_APP_OVERLAY) {
            out.attribute(null, ATT_ALLOW_APP_OVERLAY, Boolean.toString(canOverlayApps()));
        }

        out.endTag(null, TAG_CHANNEL);
    }
@@ -812,6 +863,7 @@ public final class NotificationChannel implements Parcelable {
        record.put(ATT_DELETED, Boolean.toString(isDeleted()));
        record.put(ATT_GROUP, getGroup());
        record.put(ATT_BLOCKABLE_SYSTEM, isBlockableSystem());
        record.put(ATT_ALLOW_APP_OVERLAY, canOverlayApps());
        return record;
    }

@@ -899,58 +951,36 @@ public final class NotificationChannel implements Parcelable {
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        NotificationChannel that = (NotificationChannel) o;

        if (getImportance() != that.getImportance()) return false;
        if (mBypassDnd != that.mBypassDnd) return false;
        if (getLockscreenVisibility() != that.getLockscreenVisibility()) return false;
        if (mLights != that.mLights) return false;
        if (getLightColor() != that.getLightColor()) return false;
        if (getUserLockedFields() != that.getUserLockedFields()) return false;
        if (mVibrationEnabled != that.mVibrationEnabled) return false;
        if (mShowBadge != that.mShowBadge) return false;
        if (isDeleted() != that.isDeleted()) return false;
        if (isBlockableSystem() != that.isBlockableSystem()) return false;
        if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) return false;
        if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) {
            return false;
        }
        if (getDescription() != null ? !getDescription().equals(that.getDescription())
                : that.getDescription() != null) {
            return false;
        }
        if (getSound() != null ? !getSound().equals(that.getSound()) : that.getSound() != null) {
            return false;
        }
        if (!Arrays.equals(mVibration, that.mVibration)) return false;
        if (getGroup() != null ? !getGroup().equals(that.getGroup()) : that.getGroup() != null) {
            return false;
        }
        return getAudioAttributes() != null ? getAudioAttributes().equals(that.getAudioAttributes())
                : that.getAudioAttributes() == null;

        return getImportance() == that.getImportance() &&
                mBypassDnd == that.mBypassDnd &&
                getLockscreenVisibility() == that.getLockscreenVisibility() &&
                mLights == that.mLights &&
                getLightColor() == that.getLightColor() &&
                getUserLockedFields() == that.getUserLockedFields() &&
                isFgServiceShown() == that.isFgServiceShown() &&
                mVibrationEnabled == that.mVibrationEnabled &&
                mShowBadge == that.mShowBadge &&
                isDeleted() == that.isDeleted() &&
                isBlockableSystem() == that.isBlockableSystem() &&
                mAllowAppOverlay == that.mAllowAppOverlay &&
                Objects.equals(getId(), that.getId()) &&
                Objects.equals(getName(), that.getName()) &&
                Objects.equals(mDesc, that.mDesc) &&
                Objects.equals(getSound(), that.getSound()) &&
                Arrays.equals(mVibration, that.mVibration) &&
                Objects.equals(getGroup(), that.getGroup()) &&
                Objects.equals(getAudioAttributes(), that.getAudioAttributes());
    }

    @Override
    public int hashCode() {
        int result = getId() != null ? getId().hashCode() : 0;
        result = 31 * result + (getName() != null ? getName().hashCode() : 0);
        result = 31 * result + (getDescription() != null ? getDescription().hashCode() : 0);
        result = 31 * result + getImportance();
        result = 31 * result + (mBypassDnd ? 1 : 0);
        result = 31 * result + getLockscreenVisibility();
        result = 31 * result + (getSound() != null ? getSound().hashCode() : 0);
        result = 31 * result + (mLights ? 1 : 0);
        result = 31 * result + getLightColor();
        int result = Objects.hash(getId(), getName(), mDesc, getImportance(), mBypassDnd,
                getLockscreenVisibility(), getSound(), mLights, getLightColor(),
                getUserLockedFields(),
                isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(),
                getAudioAttributes(), isBlockableSystem(), mAllowAppOverlay);
        result = 31 * result + Arrays.hashCode(mVibration);
        result = 31 * result + getUserLockedFields();
        result = 31 * result + (mVibrationEnabled ? 1 : 0);
        result = 31 * result + (mShowBadge ? 1 : 0);
        result = 31 * result + (isDeleted() ? 1 : 0);
        result = 31 * result + (getGroup() != null ? getGroup().hashCode() : 0);
        result = 31 * result + (getAudioAttributes() != null ? getAudioAttributes().hashCode() : 0);
        result = 31 * result + (isBlockableSystem() ? 1 : 0);
        return result;
    }

@@ -976,6 +1006,7 @@ public final class NotificationChannel implements Parcelable {
                + ", mGroup='" + mGroup + '\''
                + ", mAudioAttributes=" + mAudioAttributes
                + ", mBlockableSystem=" + mBlockableSystem
                + ", mAllowAppOverlay=" + mAllowAppOverlay
                + '}';
        pw.println(prefix + output);
    }
@@ -1001,6 +1032,7 @@ public final class NotificationChannel implements Parcelable {
                + ", mGroup='" + mGroup + '\''
                + ", mAudioAttributes=" + mAudioAttributes
                + ", mBlockableSystem=" + mBlockableSystem
                + ", mAllowAppOverlay=" + mAllowAppOverlay
                + '}';
    }

@@ -1034,6 +1066,7 @@ public final class NotificationChannel implements Parcelable {
            mAudioAttributes.writeToProto(proto, NotificationChannelProto.AUDIO_ATTRIBUTES);
        }
        proto.write(NotificationChannelProto.IS_BLOCKABLE_SYSTEM, mBlockableSystem);
        proto.write(NotificationChannelProto.ALLOW_APP_OVERLAY, mAllowAppOverlay);

        proto.end(token);
    }
+93 −20
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * A grouping of related notification channels. e.g., channels that all belong to a single account.
@@ -49,13 +50,33 @@ public final class NotificationChannelGroup implements Parcelable {
    private static final String ATT_DESC = "desc";
    private static final String ATT_ID = "id";
    private static final String ATT_BLOCKED = "blocked";
    private static final String ATT_ALLOW_APP_OVERLAY = "app_overlay";
    private static final String ATT_USER_LOCKED = "locked";

    private static final boolean DEFAULT_ALLOW_APP_OVERLAY = true;

    /**
     * @hide
     */
    public static final int USER_LOCKED_BLOCKED_STATE = 0x00000001;
    /**
     * @hide
     */
    @TestApi
    public static final int USER_LOCKED_ALLOW_APP_OVERLAY = 0x00000002;

    /**
     * @see #getId()
     */
    @UnsupportedAppUsage
    private final String mId;
    private CharSequence mName;
    private String mDescription;
    private boolean mBlocked;
    private List<NotificationChannel> mChannels = new ArrayList<>();
    private boolean mAllowAppOverlay = DEFAULT_ALLOW_APP_OVERLAY;
    // Bitwise representation of fields that have been changed by the user
    private int mUserLockedFields;

    /**
     * Creates a notification channel group.
@@ -89,6 +110,8 @@ public final class NotificationChannelGroup implements Parcelable {
        }
        in.readParcelableList(mChannels, NotificationChannel.class.getClassLoader());
        mBlocked = in.readBoolean();
        mAllowAppOverlay = in.readBoolean();
        mUserLockedFields = in.readInt();
    }

    private String getTrimmedString(String input) {
@@ -115,6 +138,8 @@ public final class NotificationChannelGroup implements Parcelable {
        }
        dest.writeParcelableList(mChannels, flags);
        dest.writeBoolean(mBlocked);
        dest.writeBoolean(mAllowAppOverlay);
        dest.writeInt(mUserLockedFields);
    }

    /**
@@ -155,6 +180,15 @@ public final class NotificationChannelGroup implements Parcelable {
        return mBlocked;
    }

    /**
     * Returns whether notifications posted to this channel group can display outside of the
     * notification shade, in a floating window on top of other apps. These may additionally be
     * blocked at the notification channel level, see {@link NotificationChannel#canOverlayApps()}.
     */
    public boolean canOverlayApps() {
        return mAllowAppOverlay;
    }

    /**
     * Sets the user visible description of this group.
     *
@@ -165,6 +199,21 @@ public final class NotificationChannelGroup implements Parcelable {
        mDescription = getTrimmedString(description);
    }

    /**
     * Sets whether notifications posted to this channel group can appear outside of the
     * notification shade, floating over other apps' content.
     *
     * <p>This value will be ignored for notifications that are posted to channels that do not
     * allow app overlays ({@link NotificationChannel#canOverlayApps()}.
     *
     * <p>Only modifiable before the channel is submitted to
     * {@link NotificationManager#createNotificationChannelGroup(NotificationChannelGroup)}.</p>
     * @see Notification#getAppOverlayIntent()
     */
    public void setAllowAppOverlay(boolean allowAppOverlay) {
        mAllowAppOverlay = allowAppOverlay;
    }

    /**
     * @hide
     */
@@ -187,6 +236,29 @@ public final class NotificationChannelGroup implements Parcelable {
        mChannels = channels;
    }

    /**
     * @hide
     */
    @TestApi
    public void lockFields(int field) {
        mUserLockedFields |= field;
    }

    /**
     * @hide
     */
    public void unlockFields(int field) {
        mUserLockedFields &= ~field;
    }

    /**
     * @hide
     */
    @TestApi
    public int getUserLockedFields() {
        return mUserLockedFields;
    }

    /**
     * @hide
     */
@@ -194,6 +266,7 @@ public final class NotificationChannelGroup implements Parcelable {
        // Name, id, and importance are set in the constructor.
        setDescription(parser.getAttributeValue(null, ATT_DESC));
        setBlocked(safeBool(parser, ATT_BLOCKED, false));
        setAllowAppOverlay(safeBool(parser, ATT_ALLOW_APP_OVERLAY, DEFAULT_ALLOW_APP_OVERLAY));
    }

    private static boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
@@ -216,6 +289,10 @@ public final class NotificationChannelGroup implements Parcelable {
            out.attribute(null, ATT_DESC, getDescription().toString());
        }
        out.attribute(null, ATT_BLOCKED, Boolean.toString(isBlocked()));
        if (canOverlayApps() != DEFAULT_ALLOW_APP_OVERLAY) {
            out.attribute(null, ATT_ALLOW_APP_OVERLAY, Boolean.toString(canOverlayApps()));
        }
        out.attribute(null, ATT_USER_LOCKED, Integer.toString(mUserLockedFields));

        out.endTag(null, TAG_GROUP);
    }
@@ -230,6 +307,8 @@ public final class NotificationChannelGroup implements Parcelable {
        record.put(ATT_NAME, getName());
        record.put(ATT_DESC, getDescription());
        record.put(ATT_BLOCKED, isBlocked());
        record.put(ATT_ALLOW_APP_OVERLAY, canOverlayApps());
        record.put(ATT_USER_LOCKED, mUserLockedFields);
        return record;
    }

@@ -255,30 +334,20 @@ public final class NotificationChannelGroup implements Parcelable {
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        NotificationChannelGroup that = (NotificationChannelGroup) o;

        if (isBlocked() != that.isBlocked()) return false;
        if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) return false;
        if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) {
            return false;
        }
        if (getDescription() != null ? !getDescription().equals(that.getDescription())
                : that.getDescription() != null) {
            return false;
        }
        return getChannels() != null ? getChannels().equals(that.getChannels())
                : that.getChannels() == null;
        return isBlocked() == that.isBlocked() &&
                mAllowAppOverlay == that.mAllowAppOverlay &&
                mUserLockedFields == that.mUserLockedFields &&
                Objects.equals(getId(), that.getId()) &&
                Objects.equals(getName(), that.getName()) &&
                Objects.equals(getDescription(), that.getDescription()) &&
                Objects.equals(getChannels(), that.getChannels());
    }

    @Override
    public int hashCode() {
        int result = getId() != null ? getId().hashCode() : 0;
        result = 31 * result + (getName() != null ? getName().hashCode() : 0);
        result = 31 * result + (getDescription() != null ? getDescription().hashCode() : 0);
        result = 31 * result + (isBlocked() ? 1 : 0);
        result = 31 * result + (getChannels() != null ? getChannels().hashCode() : 0);
        return result;
        return Objects.hash(getId(), getName(), getDescription(), isBlocked(), getChannels(),
                mAllowAppOverlay, mUserLockedFields);
    }

    @Override
@@ -287,6 +356,8 @@ public final class NotificationChannelGroup implements Parcelable {
        cloned.setDescription(getDescription());
        cloned.setBlocked(isBlocked());
        cloned.setChannels(getChannels());
        cloned.setAllowAppOverlay(canOverlayApps());
        cloned.lockFields(mUserLockedFields);
        return cloned;
    }

@@ -298,6 +369,8 @@ public final class NotificationChannelGroup implements Parcelable {
                + ", mDescription=" + (!TextUtils.isEmpty(mDescription) ? "hasDescription " : "")
                + ", mBlocked=" + mBlocked
                + ", mChannels=" + mChannels
                + ", mAllowAppOverlay=" + mAllowAppOverlay
                + ", mUserLockedFields=" + mUserLockedFields
                + '}';
    }

@@ -312,7 +385,7 @@ public final class NotificationChannelGroup implements Parcelable {
        for (NotificationChannel channel : mChannels) {
            channel.writeToProto(proto, NotificationChannelGroupProto.CHANNELS);
        }

        proto.write(NotificationChannelGroupProto.ALLOW_APP_OVERLAY, mAllowAppOverlay);
        proto.end(token);
    }
}
Loading