1 /* 2 * Copyright (C) 2018 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.settings.homepage.contextualcards; 18 19 import android.annotation.IntDef; 20 import android.database.Cursor; 21 import android.graphics.drawable.Drawable; 22 import android.net.Uri; 23 import android.text.TextUtils; 24 25 import androidx.annotation.LayoutRes; 26 import androidx.slice.Slice; 27 28 import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer; 29 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 33 /** 34 * Data class representing a {@link ContextualCard}. 35 */ 36 public class ContextualCard { 37 38 /** 39 * Flags indicating the type of the ContextualCard. 40 */ 41 @IntDef({CardType.DEFAULT, CardType.SLICE, CardType.LEGACY_SUGGESTION, CardType.CONDITIONAL, 42 CardType.CONDITIONAL_HEADER, CardType.CONDITIONAL_FOOTER}) 43 @Retention(RetentionPolicy.SOURCE) 44 public @interface CardType { 45 int DEFAULT = 0; 46 int SLICE = 1; 47 int LEGACY_SUGGESTION = 2; 48 int CONDITIONAL = 3; 49 int CONDITIONAL_HEADER = 4; 50 int CONDITIONAL_FOOTER = 5; 51 } 52 53 private final Builder mBuilder; 54 private final String mName; 55 @CardType 56 private final int mCardType; 57 private final double mRankingScore; 58 private final String mSliceUri; 59 private final int mCategory; 60 private final String mPackageName; 61 private final long mAppVersion; 62 private final String mTitleText; 63 private final String mSummaryText; 64 private final boolean mIsLargeCard; 65 private final Drawable mIconDrawable; 66 @LayoutRes 67 private final int mViewType; 68 private final boolean mIsPendingDismiss; 69 private final boolean mHasInlineAction; 70 private final Slice mSlice; 71 getName()72 public String getName() { 73 return mName; 74 } 75 getCardType()76 public int getCardType() { 77 return mCardType; 78 } 79 getRankingScore()80 public double getRankingScore() { 81 return mRankingScore; 82 } 83 getTextSliceUri()84 public String getTextSliceUri() { 85 return mSliceUri; 86 } 87 getSliceUri()88 public Uri getSliceUri() { 89 return Uri.parse(mSliceUri); 90 } 91 getCategory()92 public int getCategory() { 93 return mCategory; 94 } 95 getPackageName()96 public String getPackageName() { 97 return mPackageName; 98 } 99 getAppVersion()100 public long getAppVersion() { 101 return mAppVersion; 102 } 103 getTitleText()104 public String getTitleText() { 105 return mTitleText; 106 } 107 getSummaryText()108 public String getSummaryText() { 109 return mSummaryText; 110 } 111 getIconDrawable()112 public Drawable getIconDrawable() { 113 return mIconDrawable; 114 } 115 isLargeCard()116 public boolean isLargeCard() { 117 return mIsLargeCard; 118 } 119 getViewType()120 public int getViewType() { 121 return mViewType; 122 } 123 isPendingDismiss()124 public boolean isPendingDismiss() { 125 return mIsPendingDismiss; 126 } 127 hasInlineAction()128 public boolean hasInlineAction() { 129 return mHasInlineAction; 130 } 131 getSlice()132 public Slice getSlice() { 133 return mSlice; 134 } 135 mutate()136 public Builder mutate() { 137 return mBuilder; 138 } 139 ContextualCard(Builder builder)140 public ContextualCard(Builder builder) { 141 mBuilder = builder; 142 mName = builder.mName; 143 mCardType = builder.mCardType; 144 mRankingScore = builder.mRankingScore; 145 mSliceUri = builder.mSliceUri; 146 mCategory = builder.mCategory; 147 mPackageName = builder.mPackageName; 148 mAppVersion = builder.mAppVersion; 149 mTitleText = builder.mTitleText; 150 mSummaryText = builder.mSummaryText; 151 mIconDrawable = builder.mIconDrawable; 152 mIsLargeCard = builder.mIsLargeCard; 153 mViewType = builder.mViewType; 154 mIsPendingDismiss = builder.mIsPendingDismiss; 155 mHasInlineAction = builder.mHasInlineAction; 156 mSlice = builder.mSlice; 157 } 158 ContextualCard(Cursor c)159 ContextualCard(Cursor c) { 160 mBuilder = new Builder(); 161 mName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.NAME)); 162 mBuilder.setName(mName); 163 mCardType = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.TYPE)); 164 mBuilder.setCardType(mCardType); 165 mRankingScore = c.getDouble(c.getColumnIndex(CardDatabaseHelper.CardColumns.SCORE)); 166 mBuilder.setRankingScore(mRankingScore); 167 mSliceUri = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.SLICE_URI)); 168 mBuilder.setSliceUri(Uri.parse(mSliceUri)); 169 mCategory = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.CATEGORY)); 170 mBuilder.setCategory(mCategory); 171 mPackageName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.PACKAGE_NAME)); 172 mBuilder.setPackageName(mPackageName); 173 mAppVersion = c.getLong(c.getColumnIndex(CardDatabaseHelper.CardColumns.APP_VERSION)); 174 mBuilder.setAppVersion(mAppVersion); 175 mTitleText = ""; 176 mBuilder.setTitleText(mTitleText); 177 mSummaryText = ""; 178 mBuilder.setTitleText(mSummaryText); 179 mIsLargeCard = false; 180 mBuilder.setIsLargeCard(mIsLargeCard); 181 mIconDrawable = null; 182 mBuilder.setIconDrawable(mIconDrawable); 183 mViewType = getViewTypeByCardType(mCardType); 184 mBuilder.setViewType(mViewType); 185 mIsPendingDismiss = false; 186 mBuilder.setIsPendingDismiss(mIsPendingDismiss); 187 mHasInlineAction = false; 188 mBuilder.setHasInlineAction(mHasInlineAction); 189 mSlice = null; 190 mBuilder.setSlice(mSlice); 191 } 192 193 @Override hashCode()194 public int hashCode() { 195 return mName.hashCode(); 196 } 197 198 /** 199 * Note that {@link #mName} is treated as a primary key for this class and determines equality. 200 */ 201 @Override equals(Object obj)202 public boolean equals(Object obj) { 203 if (this == obj) { 204 return true; 205 } 206 if (!(obj instanceof ContextualCard)) { 207 return false; 208 } 209 final ContextualCard that = (ContextualCard) obj; 210 211 return TextUtils.equals(mName, that.mName); 212 } 213 getViewTypeByCardType(int cardType)214 private int getViewTypeByCardType(int cardType) { 215 if (cardType == CardType.SLICE) { 216 return SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH; 217 } 218 return 0; 219 } 220 221 public static class Builder { 222 private String mName; 223 private int mCardType; 224 private double mRankingScore; 225 private String mSliceUri; 226 private int mCategory; 227 private String mPackageName; 228 private long mAppVersion; 229 private String mTitleText; 230 private String mSummaryText; 231 private Drawable mIconDrawable; 232 private boolean mIsLargeCard; 233 @LayoutRes 234 private int mViewType; 235 private boolean mIsPendingDismiss; 236 private boolean mHasInlineAction; 237 private Slice mSlice; 238 setName(String name)239 public Builder setName(String name) { 240 mName = name; 241 return this; 242 } 243 setCardType(int cardType)244 public Builder setCardType(int cardType) { 245 mCardType = cardType; 246 return this; 247 } 248 setRankingScore(double rankingScore)249 public Builder setRankingScore(double rankingScore) { 250 mRankingScore = rankingScore; 251 return this; 252 } 253 setSliceUri(Uri sliceUri)254 public Builder setSliceUri(Uri sliceUri) { 255 mSliceUri = sliceUri.toString(); 256 return this; 257 } 258 setCategory(int category)259 public Builder setCategory(int category) { 260 mCategory = category; 261 return this; 262 } 263 setPackageName(String packageName)264 public Builder setPackageName(String packageName) { 265 mPackageName = packageName; 266 return this; 267 } 268 setAppVersion(long appVersion)269 public Builder setAppVersion(long appVersion) { 270 mAppVersion = appVersion; 271 return this; 272 } 273 setTitleText(String titleText)274 public Builder setTitleText(String titleText) { 275 mTitleText = titleText; 276 return this; 277 } 278 setSummaryText(String summaryText)279 public Builder setSummaryText(String summaryText) { 280 mSummaryText = summaryText; 281 return this; 282 } 283 setIconDrawable(Drawable iconDrawable)284 public Builder setIconDrawable(Drawable iconDrawable) { 285 mIconDrawable = iconDrawable; 286 return this; 287 } 288 setIsLargeCard(boolean isLargeCard)289 public Builder setIsLargeCard(boolean isLargeCard) { 290 mIsLargeCard = isLargeCard; 291 return this; 292 } 293 setViewType(@ayoutRes int viewType)294 public Builder setViewType(@LayoutRes int viewType) { 295 mViewType = viewType; 296 return this; 297 } 298 setIsPendingDismiss(boolean isPendingDismiss)299 public Builder setIsPendingDismiss(boolean isPendingDismiss) { 300 mIsPendingDismiss = isPendingDismiss; 301 return this; 302 } 303 setHasInlineAction(boolean hasInlineAction)304 public Builder setHasInlineAction(boolean hasInlineAction) { 305 mHasInlineAction = hasInlineAction; 306 return this; 307 } 308 309 /** 310 * Cache a slice created at pre-check time for later usage. 311 */ setSlice(Slice slice)312 public Builder setSlice(Slice slice) { 313 mSlice = slice; 314 return this; 315 } 316 build()317 public ContextualCard build() { 318 return new ContextualCard(this); 319 } 320 } 321 } 322