1 /* 2 * Copyright (C) 2010 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.graphics.drawable.Drawable; 20 import android.graphics.drawable.Icon; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.os.UserHandle; 24 import android.text.TextUtils; 25 26 import androidx.annotation.NonNull; 27 import androidx.annotation.Nullable; 28 29 /** 30 * Representation of an icon that should appear in the status bar. 31 * 32 * <p>This includes notifications, conversations, and icons displayed on the right side (e.g. 33 * Wifi, Vibration/Silence, Priority Modes, etc). 34 * 35 * <p>This class is {@link Parcelable} but the {@link #preloadedIcon} is not (and will be lost if 36 * the object is copied through parcelling). If {@link #preloadedIcon} is supplied, it must match 37 * the {@link #icon} resource/bitmap. 38 */ 39 public class StatusBarIcon implements Parcelable { 40 public enum Type { 41 // Notification: the sender avatar for important conversations 42 PeopleAvatar, 43 // Notification: the small icon from the notification 44 NotifSmallIcon, 45 // The wi-fi, cellular or battery icon. 46 SystemIcon, 47 // Some other icon, corresponding to a resource (possibly in a different package). 48 ResourceIcon 49 } 50 51 public enum Shape { 52 /** 53 * Icon view should use WRAP_CONTENT -- so that the horizontal space occupied depends on the 54 * icon's shape (skinny/fat icons take less/more). Most icons will want to use this option 55 * for a nicer-looking overall spacing in the status bar, as long as the icon is "known" 56 * (i.e. not coming from a 3P package). 57 */ 58 WRAP_CONTENT, 59 60 /** Icon should always be displayed in a space as wide as the status bar is tall. */ 61 FIXED_SPACE, 62 } 63 64 public UserHandle user; 65 public String pkg; 66 public Icon icon; 67 public int iconLevel; 68 public boolean visible = true; 69 public int number; 70 public CharSequence contentDescription; 71 public Type type; 72 public Shape shape; 73 74 /** 75 * Optional {@link Drawable} corresponding to {@link #icon}. This field is not parcelable, so 76 * will be lost if the object is sent to a different process. If you set it, make sure to 77 * <em>also</em> set {@link #icon} pointing to the corresponding resource. 78 */ 79 @Nullable public Drawable preloadedIcon; 80 StatusBarIcon(UserHandle user, String resPackage, Icon icon, int iconLevel, int number, CharSequence contentDescription, Type type, Shape shape)81 public StatusBarIcon(UserHandle user, String resPackage, Icon icon, int iconLevel, int number, 82 CharSequence contentDescription, Type type, Shape shape) { 83 if (icon.getType() == Icon.TYPE_RESOURCE 84 && TextUtils.isEmpty(icon.getResPackage())) { 85 // This is an odd situation where someone's managed to hand us an icon without a 86 // package inside, probably by mashing an int res into a Notification object. 87 // Now that we have the correct package name handy, let's fix it. 88 icon = Icon.createWithResource(resPackage, icon.getResId()); 89 } 90 this.pkg = resPackage; 91 this.user = user; 92 this.icon = icon; 93 this.iconLevel = iconLevel; 94 this.number = number; 95 this.contentDescription = contentDescription; 96 this.type = type; 97 this.shape = shape; 98 } 99 StatusBarIcon(UserHandle user, String resPackage, Icon icon, int iconLevel, int number, CharSequence contentDescription, Type type)100 public StatusBarIcon(UserHandle user, String resPackage, Icon icon, int iconLevel, int number, 101 CharSequence contentDescription, Type type) { 102 this(user, resPackage, icon, iconLevel, number, contentDescription, type, 103 Shape.WRAP_CONTENT); 104 } 105 StatusBarIcon(String iconPackage, UserHandle user, int iconId, int iconLevel, int number, CharSequence contentDescription, Type type)106 public StatusBarIcon(String iconPackage, UserHandle user, 107 int iconId, int iconLevel, int number, 108 CharSequence contentDescription, Type type) { 109 this(user, iconPackage, Icon.createWithResource(iconPackage, iconId), 110 iconLevel, number, contentDescription, type); 111 } 112 113 @NonNull 114 @Override toString()115 public String toString() { 116 return "StatusBarIcon(icon=" + icon 117 + ((iconLevel != 0)?(" level=" + iconLevel):"") 118 + (visible?" visible":"") 119 + " user=" + user.getIdentifier() 120 + ((number != 0)?(" num=" + number):"") 121 + " )"; 122 } 123 124 @NonNull 125 @Override clone()126 public StatusBarIcon clone() { 127 StatusBarIcon that = new StatusBarIcon(this.user, this.pkg, this.icon, 128 this.iconLevel, this.number, this.contentDescription, this.type, this.shape); 129 that.visible = this.visible; 130 that.preloadedIcon = this.preloadedIcon; 131 return that; 132 } 133 134 /** 135 * Unflatten the StatusBarIcon from a parcel. 136 */ StatusBarIcon(Parcel in)137 public StatusBarIcon(Parcel in) { 138 readFromParcel(in); 139 } 140 readFromParcel(Parcel in)141 public void readFromParcel(Parcel in) { 142 this.icon = (Icon) in.readParcelable(null, android.graphics.drawable.Icon.class); 143 this.pkg = in.readString(); 144 this.user = (UserHandle) in.readParcelable(null, android.os.UserHandle.class); 145 this.iconLevel = in.readInt(); 146 this.visible = in.readInt() != 0; 147 this.number = in.readInt(); 148 this.contentDescription = in.readCharSequence(); 149 this.type = Type.valueOf(in.readString()); 150 this.shape = Shape.valueOf(in.readString()); 151 } 152 writeToParcel(Parcel out, int flags)153 public void writeToParcel(Parcel out, int flags) { 154 out.writeParcelable(this.icon, 0); 155 out.writeString(this.pkg); 156 out.writeParcelable(this.user, 0); 157 out.writeInt(this.iconLevel); 158 out.writeInt(this.visible ? 1 : 0); 159 out.writeInt(this.number); 160 out.writeCharSequence(this.contentDescription); 161 out.writeString(this.type.name()); 162 out.writeString(this.shape.name()); 163 } 164 describeContents()165 public int describeContents() { 166 return 0; 167 } 168 169 /** 170 * Parcelable.Creator that instantiates StatusBarIcon objects 171 */ 172 public static final Parcelable.Creator<StatusBarIcon> CREATOR 173 = new Parcelable.Creator<StatusBarIcon>() 174 { 175 public StatusBarIcon createFromParcel(Parcel parcel) 176 { 177 return new StatusBarIcon(parcel); 178 } 179 180 public StatusBarIcon[] newArray(int size) 181 { 182 return new StatusBarIcon[size]; 183 } 184 }; 185 } 186 187