1 /*
2  * Copyright (C) 2017 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 
18 package com.android.settings.intelligence.search;
19 
20 import android.graphics.drawable.Drawable;
21 import android.text.TextUtils;
22 import android.util.Log;
23 
24 import java.util.List;
25 
26 /**
27  * Data class as an interface for all Search Results.
28  */
29 public class SearchResult implements Comparable<SearchResult> {
30 
31     private static final String TAG = "SearchResult";
32 
33     /**
34      * Defines the lowest rank for a search result to be considered as ranked. Results with ranks
35      * higher than this have no guarantee for sorting order.
36      */
37     public static final int BOTTOM_RANK = 10;
38 
39     /**
40      * Defines the highest rank for a search result. Used for special search results only.
41      */
42     public static final int TOP_RANK = 0;
43 
44     /**
45      * The title of the result and main text displayed.
46      * Intent Results: Displays as the primary
47      */
48     public final CharSequence title;
49 
50     /**
51      * Summary / subtitle text
52      * Intent Results: Displays the text underneath the title
53      */
54     final public CharSequence summary;
55 
56     /**
57      * An ordered list of the information hierarchy.
58      * Intent Results: Displayed a hierarchy of selections to reach the setting from the home screen
59      */
60     public final List<String> breadcrumbs;
61 
62     /**
63      * A suggestion for the ranking of the result.
64      * Based on Settings Rank:
65      * 1 is a near perfect match
66      * 9 is the weakest match
67      * TODO subject to change
68      */
69     public final int rank;
70 
71     /**
72      * Identifier for the recycler view adapter.
73      */
74     @ResultPayload.PayloadType
75     public final int viewType;
76 
77     /**
78      * Metadata for the specific result types.
79      */
80     public final ResultPayload payload;
81 
82     /**
83      * Result's icon.
84      */
85     public final Drawable icon;
86 
87     /**
88      * A unique key for this object.
89      */
90     public final String dataKey;
91 
SearchResult(Builder builder)92     protected SearchResult(Builder builder) {
93         dataKey = builder.mDataKey;
94         title = builder.mTitle;
95         summary = builder.mSummary;
96         breadcrumbs = builder.mBreadcrumbs;
97         rank = builder.mRank;
98         icon = builder.mIcon;
99         payload = builder.mResultPayload;
100         viewType = payload.getType();
101     }
102 
103     @Override
compareTo(SearchResult searchResult)104     public int compareTo(SearchResult searchResult) {
105         if (searchResult == null) {
106             return -1;
107         }
108         return this.rank - searchResult.rank;
109     }
110 
111     @Override
equals(Object that)112     public boolean equals(Object that) {
113         if (this == that) {
114             return true;
115         }
116         if (!(that instanceof SearchResult)) {
117             return false;
118         }
119         return TextUtils.equals(dataKey, ((SearchResult) that).dataKey);
120     }
121 
122     @Override
hashCode()123     public int hashCode() {
124         return dataKey.hashCode();
125     }
126 
127     public static class Builder {
128         private CharSequence mTitle;
129         private CharSequence mSummary;
130         private List<String> mBreadcrumbs;
131         private int mRank = 42;
132         private ResultPayload mResultPayload;
133         private Drawable mIcon;
134         private String mDataKey;
135 
setTitle(CharSequence title)136         public Builder setTitle(CharSequence title) {
137             mTitle = title;
138             return this;
139         }
140 
setSummary(CharSequence summary)141         public Builder setSummary(CharSequence summary) {
142             mSummary = summary;
143             return this;
144         }
145 
addBreadcrumbs(List<String> breadcrumbs)146         public Builder addBreadcrumbs(List<String> breadcrumbs) {
147             mBreadcrumbs = breadcrumbs;
148             return this;
149         }
150 
setRank(int rank)151         public Builder setRank(int rank) {
152             if (rank >= 0 && rank <= 9) {
153                 mRank = rank;
154             }
155             return this;
156         }
157 
setIcon(Drawable icon)158         public Builder setIcon(Drawable icon) {
159             mIcon = icon;
160             return this;
161         }
162 
setPayload(ResultPayload payload)163         public Builder setPayload(ResultPayload payload) {
164             mResultPayload = payload;
165             return this;
166         }
167 
setDataKey(String key)168         public Builder setDataKey(String key) {
169             mDataKey = key;
170             return this;
171         }
172 
build()173         public SearchResult build() {
174             // Check that all of the mandatory fields are set.
175             if (TextUtils.isEmpty(mTitle)) {
176                 throw new IllegalStateException("SearchResult missing title argument");
177             } else if (TextUtils.isEmpty(mDataKey)) {
178                 Log.v(TAG, "No data key on SearchResult with title: " + mTitle);
179                 throw new IllegalStateException("SearchResult missing stableId argument");
180             } else if (mResultPayload == null) {
181                 throw new IllegalStateException("SearchResult missing Payload argument");
182             }
183             return new SearchResult(this);
184         }
185     }
186 }