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.content.Context; 21 import android.graphics.drawable.Icon; 22 import android.os.Parcel; 23 24 import androidx.annotation.NonNull; 25 import androidx.annotation.Nullable; 26 import androidx.annotation.StringRes; 27 28 /** 29 * Quick Control Action that are includes as either start or end actions in {@link QCRow} 30 */ 31 public class QCActionItem extends QCItem { 32 private final boolean mIsChecked; 33 private final boolean mIsAvailable; 34 private final boolean mIsClickable; 35 private Icon mIcon; 36 private PendingIntent mAction; 37 private PendingIntent mDisabledClickAction; 38 private String mContentDescription; 39 QCActionItem(@onNull @CItemType String type, boolean isChecked, boolean isEnabled, boolean isAvailable, boolean isClickable, boolean isClickableWhileDisabled, @Nullable Icon icon, @Nullable String contentDescription, @Nullable PendingIntent action, @Nullable PendingIntent disabledClickAction)40 public QCActionItem(@NonNull @QCItemType String type, boolean isChecked, boolean isEnabled, 41 boolean isAvailable, boolean isClickable, boolean isClickableWhileDisabled, 42 @Nullable Icon icon, @Nullable String contentDescription, 43 @Nullable PendingIntent action, @Nullable PendingIntent disabledClickAction) { 44 super(type, isEnabled, isClickableWhileDisabled); 45 mIsChecked = isChecked; 46 mIsAvailable = isAvailable; 47 mIsClickable = isClickable; 48 mIcon = icon; 49 mContentDescription = contentDescription; 50 mAction = action; 51 mDisabledClickAction = disabledClickAction; 52 } 53 QCActionItem(@onNull Parcel in)54 public QCActionItem(@NonNull Parcel in) { 55 super(in); 56 mIsChecked = in.readBoolean(); 57 mIsAvailable = in.readBoolean(); 58 mIsClickable = in.readBoolean(); 59 boolean hasIcon = in.readBoolean(); 60 if (hasIcon) { 61 mIcon = Icon.CREATOR.createFromParcel(in); 62 } 63 boolean hasContentDescription = in.readBoolean(); 64 if (hasContentDescription) { 65 mContentDescription = in.readString(); 66 } 67 boolean hasAction = in.readBoolean(); 68 if (hasAction) { 69 mAction = PendingIntent.CREATOR.createFromParcel(in); 70 } 71 boolean hasDisabledClickAction = in.readBoolean(); 72 if (hasDisabledClickAction) { 73 mDisabledClickAction = PendingIntent.CREATOR.createFromParcel(in); 74 } 75 } 76 77 @Override writeToParcel(Parcel dest, int flags)78 public void writeToParcel(Parcel dest, int flags) { 79 super.writeToParcel(dest, flags); 80 dest.writeBoolean(mIsChecked); 81 dest.writeBoolean(mIsAvailable); 82 dest.writeBoolean(mIsClickable); 83 boolean includeIcon = getType().equals(QC_TYPE_ACTION_TOGGLE) && mIcon != null; 84 dest.writeBoolean(includeIcon); 85 if (includeIcon) { 86 mIcon.writeToParcel(dest, flags); 87 } 88 boolean hasContentDescription = mContentDescription != null; 89 dest.writeBoolean(hasContentDescription); 90 if (hasContentDescription) { 91 dest.writeString(mContentDescription); 92 } 93 boolean hasAction = mAction != null; 94 dest.writeBoolean(hasAction); 95 if (hasAction) { 96 mAction.writeToParcel(dest, flags); 97 } 98 boolean hasDisabledClickAction = mDisabledClickAction != null; 99 dest.writeBoolean(hasDisabledClickAction); 100 if (hasDisabledClickAction) { 101 mDisabledClickAction.writeToParcel(dest, flags); 102 } 103 } 104 105 @Override getPrimaryAction()106 public PendingIntent getPrimaryAction() { 107 return mAction; 108 } 109 110 @Override getDisabledClickAction()111 public PendingIntent getDisabledClickAction() { 112 return mDisabledClickAction; 113 } 114 isChecked()115 public boolean isChecked() { 116 return mIsChecked; 117 } 118 isAvailable()119 public boolean isAvailable() { 120 return mIsAvailable; 121 } 122 isClickable()123 public boolean isClickable() { 124 return mIsClickable; 125 } 126 127 @Nullable getIcon()128 public Icon getIcon() { 129 return mIcon; 130 } 131 132 @Nullable getContentDescription()133 public String getContentDescription() { 134 return mContentDescription; 135 } 136 137 public static Creator<QCActionItem> CREATOR = new Creator<QCActionItem>() { 138 @Override 139 public QCActionItem createFromParcel(Parcel source) { 140 return new QCActionItem(source); 141 } 142 143 @Override 144 public QCActionItem[] newArray(int size) { 145 return new QCActionItem[size]; 146 } 147 }; 148 149 /** 150 * Builder for {@link QCActionItem}. 151 */ 152 public static class Builder { 153 private final String mType; 154 private boolean mIsChecked; 155 private boolean mIsEnabled = true; 156 private boolean mIsAvailable = true; 157 private boolean mIsClickable = true; 158 private boolean mIsClickableWhileDisabled = false; 159 private Icon mIcon; 160 private PendingIntent mAction; 161 private PendingIntent mDisabledClickAction; 162 private String mContentDescription; 163 Builder(@onNull @CItemType String type)164 public Builder(@NonNull @QCItemType String type) { 165 if (!isValidType(type)) { 166 throw new IllegalArgumentException("Invalid QCActionItem type provided" + type); 167 } 168 mType = type; 169 } 170 171 /** 172 * Sets whether or not the action item should be checked. 173 */ setChecked(boolean checked)174 public Builder setChecked(boolean checked) { 175 mIsChecked = checked; 176 return this; 177 } 178 179 /** 180 * Sets whether or not the action item should be enabled. 181 */ setEnabled(boolean enabled)182 public Builder setEnabled(boolean enabled) { 183 mIsEnabled = enabled; 184 return this; 185 } 186 187 /** 188 * Sets whether or not the action item is available. 189 */ setAvailable(boolean available)190 public Builder setAvailable(boolean available) { 191 mIsAvailable = available; 192 return this; 193 } 194 195 /** 196 * Sets whether the action is clickable. This differs from available in that the style will 197 * remain as if it's enabled/available but click actions will not be processed. 198 */ setClickable(boolean clickable)199 public Builder setClickable(boolean clickable) { 200 mIsClickable = clickable; 201 return this; 202 } 203 204 /** 205 * Sets whether or not an action item should be clickable while disabled. 206 */ setClickableWhileDisabled(boolean clickable)207 public Builder setClickableWhileDisabled(boolean clickable) { 208 mIsClickableWhileDisabled = clickable; 209 return this; 210 } 211 212 /** 213 * Sets the icon for {@link QC_TYPE_ACTION_TOGGLE} actions 214 */ setIcon(@ullable Icon icon)215 public Builder setIcon(@Nullable Icon icon) { 216 mIcon = icon; 217 return this; 218 } 219 220 /** 221 * Sets the content description 222 */ setContentDescription(@ullable String contentDescription)223 public Builder setContentDescription(@Nullable String contentDescription) { 224 mContentDescription = contentDescription; 225 return this; 226 } 227 228 /** 229 * Sets the string resource to use for content description 230 */ setContentDescription(@onNull Context context, @StringRes int contentDescriptionResId)231 public Builder setContentDescription(@NonNull Context context, 232 @StringRes int contentDescriptionResId) { 233 mContentDescription = context.getString(contentDescriptionResId); 234 return this; 235 } 236 237 /** 238 * Sets the PendingIntent to be sent when the action item is clicked. 239 */ setAction(@ullable PendingIntent action)240 public Builder setAction(@Nullable PendingIntent action) { 241 mAction = action; 242 return this; 243 } 244 245 /** 246 * Sets the PendingIntent to be sent when the action item is clicked while disabled. 247 */ setDisabledClickAction(@ullable PendingIntent action)248 public Builder setDisabledClickAction(@Nullable PendingIntent action) { 249 mDisabledClickAction = action; 250 return this; 251 } 252 253 /** 254 * Builds the final {@link QCActionItem}. 255 */ build()256 public QCActionItem build() { 257 return new QCActionItem(mType, mIsChecked, mIsEnabled, mIsAvailable, mIsClickable, 258 mIsClickableWhileDisabled, mIcon, mContentDescription, mAction, 259 mDisabledClickAction); 260 } 261 isValidType(String type)262 private boolean isValidType(String type) { 263 return type.equals(QC_TYPE_ACTION_SWITCH) || type.equals(QC_TYPE_ACTION_TOGGLE); 264 } 265 } 266 } 267