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