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
18package com.android.settings.search;
19
20import android.graphics.drawable.Drawable;
21import android.text.TextUtils;
22import android.util.Log;
23
24import java.util.List;
25
26/**
27 * Data class as an interface for all Search Results.
28 */
29public 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     * Stable id for this object.
89     */
90    public final int stableId;
91
92    protected SearchResult(Builder builder) {
93        stableId = builder.mStableId;
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
104    public int compareTo(SearchResult searchResult) {
105        if (searchResult == null) {
106            return -1;
107        }
108        return this.rank - searchResult.rank;
109    }
110
111    @Override
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 this.stableId == ((SearchResult) that).stableId;
120    }
121
122    @Override
123    public int hashCode() {
124        return stableId;
125    }
126
127    public static class Builder {
128        protected CharSequence mTitle;
129        protected CharSequence mSummary;
130        protected List<String> mBreadcrumbs;
131        protected int mRank = 42;
132        protected ResultPayload mResultPayload;
133        protected Drawable mIcon;
134        protected int mStableId;
135
136        public Builder setTitle(CharSequence title) {
137            mTitle = title;
138            return this;
139        }
140
141        public Builder setSummary(CharSequence summary) {
142            mSummary = summary;
143            return this;
144        }
145
146        public Builder addBreadcrumbs(List<String> breadcrumbs) {
147            mBreadcrumbs = breadcrumbs;
148            return this;
149        }
150
151        public Builder setRank(int rank) {
152            if (rank >= 0 && rank <= 9) {
153                mRank = rank;
154            }
155            return this;
156        }
157
158        public Builder setIcon(Drawable icon) {
159            mIcon = icon;
160            return this;
161        }
162
163        public Builder setPayload(ResultPayload payload) {
164            mResultPayload = payload;
165            return this;
166        }
167
168        public Builder setStableId(int stableId) {
169            mStableId = stableId;
170            return this;
171        }
172
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 (mStableId == 0) {
178                Log.v(TAG, "No stable ID 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}