1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.statusbar;
18 
19 import android.os.Message;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.util.Log;
23 
24 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
25 
26 import java.util.ArrayDeque;
27 import java.util.Collection;
28 
29 public class NotificationVisibility implements Parcelable {
30     private static final String TAG = "NoViz";
31     private static final int MAX_POOL_SIZE = 25;
32     private static int sNexrId = 0;
33 
34     public String key;
35     public int rank;
36     public int count;
37     public boolean visible = true;
38     /** The visible location of the notification, could be e.g. notification shade or HUN. */
39     public NotificationLocation location;
40     /*package*/ int id;
41 
42     /**
43      * The UI location of the notification.
44      *
45      * There is a one-to-one mapping between this enum and
46      * MetricsProto.MetricsEvent.NotificationLocation.
47      */
48     public enum NotificationLocation {
49         LOCATION_UNKNOWN(MetricsEvent.LOCATION_UNKNOWN),
50         LOCATION_FIRST_HEADS_UP(MetricsEvent.LOCATION_FIRST_HEADS_UP), // visible heads-up
51         LOCATION_HIDDEN_TOP(MetricsEvent.LOCATION_HIDDEN_TOP), // hidden/scrolled away on the top
52         LOCATION_MAIN_AREA(MetricsEvent.LOCATION_MAIN_AREA), // visible in the shade
53         // in the bottom stack, and peeking
54         LOCATION_BOTTOM_STACK_PEEKING(MetricsEvent.LOCATION_BOTTOM_STACK_PEEKING),
55         // in the bottom stack, and hidden
56         LOCATION_BOTTOM_STACK_HIDDEN(MetricsEvent.LOCATION_BOTTOM_STACK_HIDDEN),
57         LOCATION_GONE(MetricsEvent.LOCATION_GONE); // the view isn't laid out at all
58 
59         private final int mMetricsEventNotificationLocation;
60 
NotificationLocation(int metricsEventNotificationLocation)61         NotificationLocation(int metricsEventNotificationLocation) {
62             mMetricsEventNotificationLocation = metricsEventNotificationLocation;
63         }
64 
65         /**
66          * Returns the field from MetricsEvent.NotificationLocation that corresponds to this object.
67          */
toMetricsEventEnum()68         public int toMetricsEventEnum() {
69             return mMetricsEventNotificationLocation;
70         }
71     }
72 
NotificationVisibility()73     private NotificationVisibility() {
74         id = sNexrId++;
75     }
76 
NotificationVisibility(String key, int rank, int count, boolean visible, NotificationLocation location)77     private NotificationVisibility(String key, int rank, int count, boolean visible,
78             NotificationLocation location) {
79         this();
80         this.key = key;
81         this.rank = rank;
82         this.count = count;
83         this.visible = visible;
84         this.location = location;
85     }
86 
87     @Override
toString()88     public String toString() {
89         return "NotificationVisibility(id=" + id
90                 + " key=" + key
91                 + " rank=" + rank
92                 + " count=" + count
93                 + (visible?" visible":"")
94                 + " location=" + location.name()
95                 + " )";
96     }
97 
98     @Override
clone()99     public NotificationVisibility clone() {
100         return obtain(this.key, this.rank, this.count, this.visible, this.location);
101     }
102 
103     @Override
hashCode()104     public int hashCode() {
105         // allow lookups by key, which _should_ never be null.
106         return key == null ? 0 : key.hashCode();
107     }
108 
109     @Override
equals(Object that)110     public boolean equals(Object that) {
111         // allow lookups by key, which _should_ never be null.
112         if (that instanceof NotificationVisibility) {
113             NotificationVisibility thatViz = (NotificationVisibility) that;
114             return (key == null && thatViz.key == null) || key.equals(thatViz.key);
115         }
116         return false;
117     }
118 
119     @Override
describeContents()120     public int describeContents() {
121         return 0;
122     }
123 
124     @Override
writeToParcel(Parcel out, int flags)125     public void writeToParcel(Parcel out, int flags) {
126         out.writeString(this.key);
127         out.writeInt(this.rank);
128         out.writeInt(this.count);
129         out.writeInt(this.visible ? 1 : 0);
130         out.writeString(this.location.name());
131     }
132 
readFromParcel(Parcel in)133     private void readFromParcel(Parcel in) {
134         this.key = in.readString();
135         this.rank = in.readInt();
136         this.count = in.readInt();
137         this.visible = in.readInt() != 0;
138         this.location = NotificationLocation.valueOf(in.readString());
139     }
140 
141     /**
142      * Create a new NotificationVisibility object.
143      */
obtain(String key, int rank, int count, boolean visible)144     public static NotificationVisibility obtain(String key, int rank, int count, boolean visible) {
145         return obtain(key, rank, count, visible,
146                 NotificationVisibility.NotificationLocation.LOCATION_UNKNOWN);
147     }
148 
149     /**
150      * Create a new NotificationVisibility object.
151      */
obtain(String key, int rank, int count, boolean visible, NotificationLocation location)152     public static NotificationVisibility obtain(String key, int rank, int count, boolean visible,
153             NotificationLocation location) {
154         NotificationVisibility vo = obtain();
155         vo.key = key;
156         vo.rank = rank;
157         vo.count = count;
158         vo.visible = visible;
159         vo.location = location;
160         return vo;
161     }
162 
obtain(Parcel in)163     private static NotificationVisibility obtain(Parcel in) {
164         NotificationVisibility vo = obtain();
165         vo.readFromParcel(in);
166         return vo;
167     }
168 
obtain()169     private static NotificationVisibility obtain() {
170         return new NotificationVisibility();
171     }
172 
173     /**
174      * Return a NotificationVisibility instance to the global pool.
175      * <p>
176      * You MUST NOT touch the NotificationVisibility after calling this function because it has
177      * effectively been freed.
178      * </p>
179      */
recycle()180     public void recycle() {
181         // With a modern GC, this is no longer useful for objects this small.
182     }
183 
184     /**
185      * Parcelable.Creator that instantiates NotificationVisibility objects
186      */
187     public static final Parcelable.Creator<NotificationVisibility> CREATOR
188             = new Parcelable.Creator<NotificationVisibility>()
189     {
190         public NotificationVisibility createFromParcel(Parcel parcel)
191         {
192             return obtain(parcel);
193         }
194 
195         public NotificationVisibility[] newArray(int size)
196         {
197             return new NotificationVisibility[size];
198         }
199     };
200 }
201 
202