1 /*
2  * Copyright (C) 2022 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 package com.android.quicksearchbox
17 
18 import android.content.ComponentName
19 import android.content.Intent
20 import com.google.common.annotations.VisibleForTesting
21 
22 /**
23  * Holds data for each suggest item including the display data and how to launch the result. Used
24  * for passing from the provider to the suggest cursor.
25  */
26 class SuggestionData(override val suggestionSource: Source?) : Suggestion {
27   private var mFormat: String? = null
28   private var mText1: String? = null
29   private var mText2: String? = null
30   private var mText2Url: String? = null
31   private var mIcon1: String? = null
32   private var mIcon2: String? = null
33   private var mShortcutId: String? = null
34   override var isSpinnerWhileRefreshing = false
35     private set
36   private var mIntentAction: String? = null
37   private var mIntentData: String? = null
38   var intentExtraData: String? = null
39     private set
40   private var mSuggestionQuery: String? = null
41   private var mLogType: String? = null
42   override var isSuggestionShortcut = false
43     private set
44   override var isHistorySuggestion = false
45     private set
46   private var mExtras: SuggestionExtras? = null
47   override val suggestionFormat: String
48     get() = mFormat!!
49   override val suggestionText1: String
50     get() = mText1!!
51   override val suggestionText2: String
52     get() = mText2!!
53   override val suggestionText2Url: String
54     get() = mText2Url!!
55   override val suggestionIcon1: String
56     get() = mIcon1!!
57   override val suggestionIcon2: String
58     get() = mIcon2!!
59   override val shortcutId: String
60     get() = mShortcutId!!
61   override val suggestionIntentAction: String?
62     get() = mIntentAction ?: suggestionSource?.defaultIntentAction
63   override val suggestionIntentComponent: ComponentName?
64     get() = suggestionSource?.intentComponent
65   override val suggestionIntentDataString: String
66     get() = mIntentData!!
67   override val suggestionIntentExtraData: String
68     get() = intentExtraData!!
69   override val suggestionQuery: String
70     get() = mSuggestionQuery!!
71   override val suggestionLogType: String
72     get() = mLogType!!
73   override val isWebSearchSuggestion: Boolean
74     get() = Intent.ACTION_WEB_SEARCH.equals(suggestionIntentAction)
75 
76   @VisibleForTesting
setFormatnull77   fun setFormat(format: String?): SuggestionData {
78     mFormat = format
79     return this
80   }
81 
82   @VisibleForTesting
setText1null83   fun setText1(text1: String?): SuggestionData {
84     mText1 = text1
85     return this
86   }
87 
88   @VisibleForTesting
setText2null89   fun setText2(text2: String?): SuggestionData {
90     mText2 = text2
91     return this
92   }
93 
94   @VisibleForTesting
setText2Urlnull95   fun setText2Url(text2Url: String?): SuggestionData {
96     mText2Url = text2Url
97     return this
98   }
99 
100   @VisibleForTesting
setIcon1null101   fun setIcon1(icon1: String?): SuggestionData {
102     mIcon1 = icon1
103     return this
104   }
105 
106   @VisibleForTesting
setIcon2null107   fun setIcon2(icon2: String?): SuggestionData {
108     mIcon2 = icon2
109     return this
110   }
111 
112   @VisibleForTesting
setIntentActionnull113   fun setIntentAction(intentAction: String?): SuggestionData {
114     mIntentAction = intentAction
115     return this
116   }
117 
118   @VisibleForTesting
setIntentDatanull119   fun setIntentData(intentData: String?): SuggestionData {
120     mIntentData = intentData
121     return this
122   }
123 
124   @VisibleForTesting
setIntentExtraDatanull125   fun setIntentExtraData(intentExtraData: String?): SuggestionData {
126     this.intentExtraData = intentExtraData
127     return this
128   }
129 
130   @VisibleForTesting
setSuggestionQuerynull131   fun setSuggestionQuery(suggestionQuery: String?): SuggestionData {
132     mSuggestionQuery = suggestionQuery
133     return this
134   }
135 
136   @VisibleForTesting
setShortcutIdnull137   fun setShortcutId(shortcutId: String?): SuggestionData {
138     mShortcutId = shortcutId
139     return this
140   }
141 
142   @VisibleForTesting
setSpinnerWhileRefreshingnull143   fun setSpinnerWhileRefreshing(spinnerWhileRefreshing: Boolean): SuggestionData {
144     isSpinnerWhileRefreshing = spinnerWhileRefreshing
145     return this
146   }
147 
148   @VisibleForTesting
setSuggestionLogTypenull149   fun setSuggestionLogType(logType: String?): SuggestionData {
150     mLogType = logType
151     return this
152   }
153 
154   @VisibleForTesting
setIsShortcutnull155   fun setIsShortcut(isShortcut: Boolean): SuggestionData {
156     isSuggestionShortcut = isShortcut
157     return this
158   }
159 
160   @VisibleForTesting
setIsHistorynull161   fun setIsHistory(isHistory: Boolean): SuggestionData {
162     isHistorySuggestion = isHistory
163     return this
164   }
165 
166   @Override
hashCodenull167   override fun hashCode(): Int {
168     val prime = 31
169     var result = 1
170     result = prime * result + if (mFormat == null) 0 else mFormat.hashCode()
171     result = prime * result + if (mIcon1 == null) 0 else mIcon1.hashCode()
172     result = prime * result + if (mIcon2 == null) 0 else mIcon2.hashCode()
173     result = prime * result + if (mIntentAction == null) 0 else mIntentAction.hashCode()
174     result = prime * result + if (mIntentData == null) 0 else mIntentData.hashCode()
175     result = prime * result + if (intentExtraData == null) 0 else intentExtraData.hashCode()
176     result = prime * result + if (mLogType == null) 0 else mLogType.hashCode()
177     result = prime * result + if (mShortcutId == null) 0 else mShortcutId.hashCode()
178     result = prime * result + if (suggestionSource == null) 0 else suggestionSource.hashCode()
179     result = prime * result + if (isSpinnerWhileRefreshing) 1231 else 1237
180     result = prime * result + if (mSuggestionQuery == null) 0 else mSuggestionQuery.hashCode()
181     result = prime * result + if (mText1 == null) 0 else mText1.hashCode()
182     result = prime * result + if (mText2 == null) 0 else mText2.hashCode()
183     return result
184   }
185 
186   @Override
equalsnull187   override fun equals(other: Any?): Boolean {
188     if (this === other) return true
189     if (other == null) return false
190     if (this::class !== other::class) return false
191     val suggestionData = other as SuggestionData
192     if (mFormat == null) {
193       if (suggestionData.mFormat != null) return false
194     } else if (!mFormat.equals(suggestionData.mFormat)) return false
195     if (mIcon1 == null) {
196       if (suggestionData.mIcon1 != null) return false
197     } else if (!mIcon1.equals(suggestionData.mIcon1)) return false
198     if (mIcon2 == null) {
199       if (suggestionData.mIcon2 != null) return false
200     } else if (!mIcon2.equals(suggestionData.mIcon2)) return false
201     if (mIntentAction == null) {
202       if (suggestionData.mIntentAction != null) return false
203     } else if (!mIntentAction.equals(suggestionData.mIntentAction)) return false
204     if (mIntentData == null) {
205       if (suggestionData.mIntentData != null) return false
206     } else if (!mIntentData.equals(suggestionData.mIntentData)) return false
207     if (intentExtraData == null) {
208       if (suggestionData.intentExtraData != null) return false
209     } else if (!intentExtraData.equals(suggestionData.intentExtraData)) return false
210     if (mLogType == null) {
211       if (suggestionData.mLogType != null) return false
212     } else if (!mLogType.equals(suggestionData.mLogType)) return false
213     if (mShortcutId == null) {
214       if (suggestionData.mShortcutId != null) return false
215     } else if (!mShortcutId.equals(suggestionData.mShortcutId)) return false
216     if (suggestionSource == null) {
217       if (suggestionData.suggestionSource != null) return false
218     } else if (!suggestionSource.equals(suggestionData.suggestionSource)) return false
219     if (isSpinnerWhileRefreshing != suggestionData.isSpinnerWhileRefreshing) return false
220     if (mSuggestionQuery == null) {
221       if (suggestionData.mSuggestionQuery != null) return false
222     } else if (!mSuggestionQuery.equals(suggestionData.mSuggestionQuery)) return false
223     if (mText1 == null) {
224       if (suggestionData.mText1 != null) return false
225     } else if (!mText1.equals(suggestionData.mText1)) return false
226     if (mText2 == null) {
227       if (suggestionData.mText2 != null) return false
228     } else if (!mText2.equals(suggestionData.mText2)) return false
229     return true
230   }
231 
232   /**
233    * Returns a string representation of the contents of this SuggestionData, for debugging purposes.
234    */
235   @Override
toStringnull236   override fun toString(): String {
237     val builder: StringBuilder = StringBuilder("SuggestionData(")
238     appendField(builder, "source", suggestionSource!!.name)
239     appendField(builder, "text1", mText1)
240     appendField(builder, "intentAction", mIntentAction)
241     appendField(builder, "intentData", mIntentData)
242     appendField(builder, "query", mSuggestionQuery)
243     appendField(builder, "shortcutid", mShortcutId)
244     appendField(builder, "logtype", mLogType)
245     return builder.toString()
246   }
247 
appendFieldnull248   private fun appendField(builder: StringBuilder, name: String, value: String?) {
249     if (value != null) {
250       builder.append(",").append(name).append("=").append(value)
251     }
252   }
253 
254   @set:VisibleForTesting
255   override var extras: SuggestionExtras?
256     get() = mExtras
257     set(extras) {
258       mExtras = extras
259     }
260 }
261