blob: 2b4c24cbb0699dac1942456397d32bddc3c4fe08 [file] [log] [blame]
/**
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.service.notification;
import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.RemoteInput;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Information about how the user has interacted with a given notification.
* @hide
*/
@TestApi
@SystemApi
public final class NotificationStats implements Parcelable {
private boolean mSeen;
private boolean mExpanded;
private boolean mDirectReplied;
private boolean mSnoozed;
private boolean mViewedSettings;
private boolean mInteracted;
/** @hide */
@IntDef(prefix = { "DISMISSAL_SURFACE_" }, value = {
DISMISSAL_NOT_DISMISSED, DISMISSAL_OTHER, DISMISSAL_PEEK, DISMISSAL_AOD, DISMISSAL_SHADE
})
@Retention(RetentionPolicy.SOURCE)
public @interface DismissalSurface {}
private @DismissalSurface int mDismissalSurface = DISMISSAL_NOT_DISMISSED;
/**
* Notification has not been dismissed yet.
*/
public static final int DISMISSAL_NOT_DISMISSED = -1;
/**
* Notification has been dismissed from a {@link NotificationListenerService} or the app
* itself.
*/
public static final int DISMISSAL_OTHER = 0;
/**
* Notification has been dismissed while peeking.
*/
public static final int DISMISSAL_PEEK = 1;
/**
* Notification has been dismissed from always on display.
*/
public static final int DISMISSAL_AOD = 2;
/**
* Notification has been dismissed from the notification shade.
*/
public static final int DISMISSAL_SHADE = 3;
/** @hide */
@IntDef(prefix = { "DISMISS_SENTIMENT_" }, value = {
DISMISS_SENTIMENT_UNKNOWN, DISMISS_SENTIMENT_NEGATIVE, DISMISS_SENTIMENT_NEUTRAL,
DISMISS_SENTIMENT_POSITIVE
})
@Retention(RetentionPolicy.SOURCE)
public @interface DismissalSentiment {}
/**
* No information is available about why this notification was dismissed, or the notification
* isn't dismissed yet.
*/
public static final int DISMISS_SENTIMENT_UNKNOWN = -1000;
/**
* The user indicated while dismissing that they did not like the notification.
*/
public static final int DISMISS_SENTIMENT_NEGATIVE = 0;
/**
* The user didn't indicate one way or another how they felt about the notification while
* dismissing it.
*/
public static final int DISMISS_SENTIMENT_NEUTRAL = 1;
/**
* The user indicated while dismissing that they did like the notification.
*/
public static final int DISMISS_SENTIMENT_POSITIVE = 2;
private @DismissalSentiment
int mDismissalSentiment = DISMISS_SENTIMENT_UNKNOWN;
public NotificationStats() {
}
/**
* @hide
*/
@SystemApi
protected NotificationStats(Parcel in) {
mSeen = in.readByte() != 0;
mExpanded = in.readByte() != 0;
mDirectReplied = in.readByte() != 0;
mSnoozed = in.readByte() != 0;
mViewedSettings = in.readByte() != 0;
mInteracted = in.readByte() != 0;
mDismissalSurface = in.readInt();
mDismissalSentiment = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (mSeen ? 1 : 0));
dest.writeByte((byte) (mExpanded ? 1 : 0));
dest.writeByte((byte) (mDirectReplied ? 1 : 0));
dest.writeByte((byte) (mSnoozed ? 1 : 0));
dest.writeByte((byte) (mViewedSettings ? 1 : 0));
dest.writeByte((byte) (mInteracted ? 1 : 0));
dest.writeInt(mDismissalSurface);
dest.writeInt(mDismissalSentiment);
}
@Override
public int describeContents() {
return 0;
}
public static final @android.annotation.NonNull Creator<NotificationStats> CREATOR = new Creator<NotificationStats>() {
@Override
public NotificationStats createFromParcel(Parcel in) {
return new NotificationStats(in);
}
@Override
public NotificationStats[] newArray(int size) {
return new NotificationStats[size];
}
};
/**
* Returns whether the user has seen this notification at least once.
*/
public boolean hasSeen() {
return mSeen;
}
/**
* Records that the user as seen this notification at least once.
*/
public void setSeen() {
mSeen = true;
}
/**
* Returns whether the user has expanded this notification at least once.
*/
public boolean hasExpanded() {
return mExpanded;
}
/**
* Records that the user has expanded this notification at least once.
*/
public void setExpanded() {
mExpanded = true;
mInteracted = true;
}
/**
* Returns whether the user has replied to a notification that has a
* {@link android.app.Notification.Action.Builder#addRemoteInput(RemoteInput) direct reply} at
* least once.
*/
public boolean hasDirectReplied() {
return mDirectReplied;
}
/**
* Records that the user has replied to a notification that has a
* {@link android.app.Notification.Action.Builder#addRemoteInput(RemoteInput) direct reply}
* at least once.
*/
public void setDirectReplied() {
mDirectReplied = true;
mInteracted = true;
}
/**
* Returns whether the user has snoozed this notification at least once.
*/
public boolean hasSnoozed() {
return mSnoozed;
}
/**
* Records that the user has snoozed this notification at least once.
*/
public void setSnoozed() {
mSnoozed = true;
mInteracted = true;
}
/**
* Returns whether the user has viewed the in-shade settings for this notification at least
* once.
*/
public boolean hasViewedSettings() {
return mViewedSettings;
}
/**
* Records that the user has viewed the in-shade settings for this notification at least once.
*/
public void setViewedSettings() {
mViewedSettings = true;
mInteracted = true;
}
/**
* Returns whether the user has interacted with this notification beyond having viewed it.
*/
public boolean hasInteracted() {
return mInteracted;
}
/**
* Returns from which surface the notification was dismissed.
*/
public @DismissalSurface int getDismissalSurface() {
return mDismissalSurface;
}
/**
* Returns from which surface the notification was dismissed.
*/
public void setDismissalSurface(@DismissalSurface int dismissalSurface) {
mDismissalSurface = dismissalSurface;
}
/**
* Records whether the user indicated how they felt about a notification before or
* during dismissal.
*/
public void setDismissalSentiment(@DismissalSentiment int dismissalSentiment) {
mDismissalSentiment = dismissalSentiment;
}
/**
* Returns how the user indicated they felt about a notification before or during dismissal.
*/
public @DismissalSentiment int getDismissalSentiment() {
return mDismissalSentiment;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NotificationStats that = (NotificationStats) o;
if (mSeen != that.mSeen) return false;
if (mExpanded != that.mExpanded) return false;
if (mDirectReplied != that.mDirectReplied) return false;
if (mSnoozed != that.mSnoozed) return false;
if (mViewedSettings != that.mViewedSettings) return false;
if (mInteracted != that.mInteracted) return false;
return mDismissalSurface == that.mDismissalSurface;
}
@Override
public int hashCode() {
int result = (mSeen ? 1 : 0);
result = 31 * result + (mExpanded ? 1 : 0);
result = 31 * result + (mDirectReplied ? 1 : 0);
result = 31 * result + (mSnoozed ? 1 : 0);
result = 31 * result + (mViewedSettings ? 1 : 0);
result = 31 * result + (mInteracted ? 1 : 0);
result = 31 * result + mDismissalSurface;
return result;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("NotificationStats{");
sb.append("mSeen=").append(mSeen);
sb.append(", mExpanded=").append(mExpanded);
sb.append(", mDirectReplied=").append(mDirectReplied);
sb.append(", mSnoozed=").append(mSnoozed);
sb.append(", mViewedSettings=").append(mViewedSettings);
sb.append(", mInteracted=").append(mInteracted);
sb.append(", mDismissalSurface=").append(mDismissalSurface);
sb.append('}');
return sb.toString();
}
}