1 /* 2 * Copyright (C) 2021 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.car.qc; 18 19 import android.app.PendingIntent; 20 import android.graphics.drawable.Icon; 21 import android.os.Parcel; 22 23 import androidx.annotation.NonNull; 24 import androidx.annotation.Nullable; 25 26 import java.util.ArrayList; 27 import java.util.Collections; 28 import java.util.List; 29 30 /** 31 * Quick Control Row Element 32 * --------------------------------------- 33 * | | Title | | 34 * | StartItems | Subtitle | EndItems | 35 * | | ActionText | | 36 * | | Sliders | | 37 * --------------------------------------- 38 */ 39 public class QCRow extends QCItem { 40 private final String mTitle; 41 private final String mSubtitle; 42 private final String mActionText; 43 @QCCategory 44 private final int mCategory; 45 private final Icon mStartIcon; 46 private final boolean mIsStartIconTintable; 47 private final QCSlider mSlider; 48 private final List<QCActionItem> mStartItems; 49 private final List<QCActionItem> mEndItems; 50 private final PendingIntent mPrimaryAction; 51 private PendingIntent mDisabledClickAction; QCRow(@ullable String title, @Nullable String subtitle, @Nullable String actionText, @QCCategory int category, boolean isEnabled, boolean isClickableWhileDisabled, @Nullable PendingIntent primaryAction, @Nullable PendingIntent disabledClickAction, @Nullable Icon startIcon, boolean isIconTintable, @Nullable QCSlider slider, @NonNull List<QCActionItem> startItems, @NonNull List<QCActionItem> endItems)52 public QCRow(@Nullable String title, @Nullable String subtitle, 53 @Nullable String actionText, @QCCategory int category, 54 boolean isEnabled, boolean isClickableWhileDisabled, 55 @Nullable PendingIntent primaryAction, 56 @Nullable PendingIntent disabledClickAction, @Nullable Icon startIcon, 57 boolean isIconTintable, @Nullable QCSlider slider, 58 @NonNull List<QCActionItem> startItems, @NonNull List<QCActionItem> endItems) { 59 super(QC_TYPE_ROW, isEnabled, isClickableWhileDisabled); 60 mTitle = title; 61 mSubtitle = subtitle; 62 mActionText = actionText; 63 mCategory = category; 64 mPrimaryAction = primaryAction; 65 mDisabledClickAction = disabledClickAction; 66 mStartIcon = startIcon; 67 mIsStartIconTintable = isIconTintable; 68 mSlider = slider; 69 mStartItems = Collections.unmodifiableList(startItems); 70 mEndItems = Collections.unmodifiableList(endItems); 71 } 72 QCRow(@onNull Parcel in)73 public QCRow(@NonNull Parcel in) { 74 super(in); 75 mTitle = in.readString(); 76 mSubtitle = in.readString(); 77 mActionText = in.readString(); 78 mCategory = in.readInt(); 79 boolean hasIcon = in.readBoolean(); 80 if (hasIcon) { 81 mStartIcon = Icon.CREATOR.createFromParcel(in); 82 } else { 83 mStartIcon = null; 84 } 85 mIsStartIconTintable = in.readBoolean(); 86 boolean hasSlider = in.readBoolean(); 87 if (hasSlider) { 88 mSlider = QCSlider.CREATOR.createFromParcel(in); 89 } else { 90 mSlider = null; 91 } 92 List<QCActionItem> startItems = new ArrayList<>(); 93 int startItemCount = in.readInt(); 94 for (int i = 0; i < startItemCount; i++) { 95 startItems.add(QCActionItem.CREATOR.createFromParcel(in)); 96 } 97 mStartItems = Collections.unmodifiableList(startItems); 98 List<QCActionItem> endItems = new ArrayList<>(); 99 int endItemCount = in.readInt(); 100 for (int i = 0; i < endItemCount; i++) { 101 endItems.add(QCActionItem.CREATOR.createFromParcel(in)); 102 } 103 mEndItems = Collections.unmodifiableList(endItems); 104 boolean hasPrimaryAction = in.readBoolean(); 105 if (hasPrimaryAction) { 106 mPrimaryAction = PendingIntent.CREATOR.createFromParcel(in); 107 } else { 108 mPrimaryAction = null; 109 } 110 boolean hasDisabledClickAction = in.readBoolean(); 111 if (hasDisabledClickAction) { 112 mDisabledClickAction = PendingIntent.CREATOR.createFromParcel(in); 113 } else { 114 mDisabledClickAction = null; 115 } 116 } 117 118 @Override writeToParcel(Parcel dest, int flags)119 public void writeToParcel(Parcel dest, int flags) { 120 super.writeToParcel(dest, flags); 121 dest.writeString(mTitle); 122 dest.writeString(mSubtitle); 123 dest.writeString(mActionText); 124 dest.writeInt(mCategory); 125 boolean hasStartIcon = mStartIcon != null; 126 dest.writeBoolean(hasStartIcon); 127 if (hasStartIcon) { 128 mStartIcon.writeToParcel(dest, flags); 129 } 130 dest.writeBoolean(mIsStartIconTintable); 131 boolean hasSlider = mSlider != null; 132 dest.writeBoolean(hasSlider); 133 if (hasSlider) { 134 mSlider.writeToParcel(dest, flags); 135 } 136 dest.writeInt(mStartItems.size()); 137 for (QCActionItem startItem : mStartItems) { 138 startItem.writeToParcel(dest, flags); 139 } 140 dest.writeInt(mEndItems.size()); 141 for (QCActionItem endItem : mEndItems) { 142 endItem.writeToParcel(dest, flags); 143 } 144 boolean hasPrimaryAction = mPrimaryAction != null; 145 dest.writeBoolean(hasPrimaryAction); 146 if (hasPrimaryAction) { 147 mPrimaryAction.writeToParcel(dest, flags); 148 } 149 boolean hasDisabledClickAction = mDisabledClickAction != null; 150 dest.writeBoolean(hasDisabledClickAction); 151 if (hasDisabledClickAction) { 152 mDisabledClickAction.writeToParcel(dest, flags); 153 } 154 } 155 156 @Override getPrimaryAction()157 public PendingIntent getPrimaryAction() { 158 return mPrimaryAction; 159 } 160 161 @Override getDisabledClickAction()162 public PendingIntent getDisabledClickAction() { 163 return mDisabledClickAction; 164 } 165 166 @Nullable getTitle()167 public String getTitle() { 168 return mTitle; 169 } 170 171 @Nullable getSubtitle()172 public String getSubtitle() { 173 return mSubtitle; 174 } 175 176 @Nullable getActionText()177 public String getActionText() { 178 return mActionText; 179 } 180 181 @QCCategory getCategory()182 public int getCategory() { 183 return mCategory; 184 } 185 186 @Nullable getStartIcon()187 public Icon getStartIcon() { 188 return mStartIcon; 189 } 190 isStartIconTintable()191 public boolean isStartIconTintable() { 192 return mIsStartIconTintable; 193 } 194 195 @Nullable getSlider()196 public QCSlider getSlider() { 197 return mSlider; 198 } 199 200 @NonNull getStartItems()201 public List<QCActionItem> getStartItems() { 202 return mStartItems; 203 } 204 205 @NonNull getEndItems()206 public List<QCActionItem> getEndItems() { 207 return mEndItems; 208 } 209 210 public static Creator<QCRow> CREATOR = new Creator<QCRow>() { 211 @Override 212 public QCRow createFromParcel(Parcel source) { 213 return new QCRow(source); 214 } 215 216 @Override 217 public QCRow[] newArray(int size) { 218 return new QCRow[size]; 219 } 220 }; 221 222 /** 223 * Builder for {@link QCRow}. 224 */ 225 public static class Builder { 226 private final List<QCActionItem> mStartItems = new ArrayList<>(); 227 private final List<QCActionItem> mEndItems = new ArrayList<>(); 228 private Icon mStartIcon; 229 private boolean mIsStartIconTintable = true; 230 private String mTitle; 231 private String mSubtitle; 232 private String mActionText; 233 private int mCategory = QCCategory.NORMAL; 234 private boolean mIsEnabled = true; 235 private boolean mIsClickableWhileDisabled = false; 236 private QCSlider mSlider; 237 private PendingIntent mPrimaryAction; 238 private PendingIntent mDisabledClickAction; 239 240 /** 241 * Sets the row title. 242 */ setTitle(@ullable String title)243 public Builder setTitle(@Nullable String title) { 244 mTitle = title; 245 return this; 246 } 247 248 /** 249 * Sets the row subtitle. 250 */ setSubtitle(@ullable String subtitle)251 public Builder setSubtitle(@Nullable String subtitle) { 252 mSubtitle = subtitle; 253 return this; 254 } 255 256 /** 257 * Sets the row action text. 258 */ setActionText(@ullable String actionText)259 public Builder setActionText(@Nullable String actionText) { 260 mActionText = actionText; 261 return this; 262 } 263 264 /** 265 * Sets the row category. 266 */ setCategory(@CCategory int category)267 public Builder setCategory(@QCCategory int category) { 268 mCategory = category; 269 return this; 270 } 271 272 /** 273 * Sets whether or not the row is enabled. Note that this only affects the main row area, 274 * not the action items contained within the row. 275 */ setEnabled(boolean enabled)276 public Builder setEnabled(boolean enabled) { 277 mIsEnabled = enabled; 278 return this; 279 } 280 281 /** 282 * Sets whether or not the row should be clickable while disabled. 283 */ setClickableWhileDisabled(boolean clickable)284 public Builder setClickableWhileDisabled(boolean clickable) { 285 mIsClickableWhileDisabled = clickable; 286 return this; 287 } 288 289 /** 290 * Sets the row icon. 291 */ setIcon(@ullable Icon icon)292 public Builder setIcon(@Nullable Icon icon) { 293 mStartIcon = icon; 294 return this; 295 } 296 297 /** 298 * Sets whether or not the row icon is tintable. 299 */ setIconTintable(boolean tintable)300 public Builder setIconTintable(boolean tintable) { 301 mIsStartIconTintable = tintable; 302 return this; 303 } 304 305 /** 306 * Adds a {@link QCSlider} to the slider area. 307 */ addSlider(@ullable QCSlider slider)308 public Builder addSlider(@Nullable QCSlider slider) { 309 mSlider = slider; 310 return this; 311 } 312 313 /** 314 * Sets the PendingIntent to be sent when the row is clicked. 315 */ setPrimaryAction(@ullable PendingIntent action)316 public Builder setPrimaryAction(@Nullable PendingIntent action) { 317 mPrimaryAction = action; 318 return this; 319 } 320 321 /** 322 * Sets the PendingIntent to be sent when the action item is clicked while disabled. 323 */ setDisabledClickAction(@ullable PendingIntent action)324 public Builder setDisabledClickAction(@Nullable PendingIntent action) { 325 mDisabledClickAction = action; 326 return this; 327 } 328 329 /** 330 * Adds a {@link QCActionItem} to the start items area. 331 */ addStartItem(@onNull QCActionItem item)332 public Builder addStartItem(@NonNull QCActionItem item) { 333 mStartItems.add(item); 334 return this; 335 } 336 337 /** 338 * Adds a {@link QCActionItem} to the end items area. 339 */ addEndItem(@onNull QCActionItem item)340 public Builder addEndItem(@NonNull QCActionItem item) { 341 mEndItems.add(item); 342 return this; 343 } 344 345 /** 346 * Builds the final {@link QCRow}. 347 */ build()348 public QCRow build() { 349 return new QCRow(mTitle, mSubtitle, mActionText, mCategory, mIsEnabled, 350 mIsClickableWhileDisabled, mPrimaryAction, mDisabledClickAction, mStartIcon, 351 mIsStartIconTintable, mSlider, mStartItems, mEndItems); 352 } 353 } 354 } 355