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