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.content.Context;
21 import androidx.annotation.VisibleForTesting;
22 import android.text.TextUtils;
23 import android.util.Log;
24 import android.util.Pair;
25 import android.view.View;
26 
27 import com.android.settings.intelligence.search.indexing.DatabaseIndexingManager;
28 import com.android.settings.intelligence.search.indexing.IndexData;
29 import com.android.settings.intelligence.search.indexing.IndexingCallback;
30 import com.android.settings.intelligence.search.query.AccessibilityServiceResultTask;
31 import com.android.settings.intelligence.search.query.DatabaseResultTask;
32 import com.android.settings.intelligence.search.query.InputDeviceResultTask;
33 import com.android.settings.intelligence.search.query.InstalledAppResultTask;
34 import com.android.settings.intelligence.search.query.SearchQueryTask;
35 import com.android.settings.intelligence.search.savedqueries.SavedQueryLoader;
36 import com.android.settings.intelligence.search.sitemap.SiteMapManager;
37 
38 import java.util.ArrayList;
39 import java.util.List;
40 import java.util.Locale;
41 import java.util.concurrent.ExecutorService;
42 import java.util.concurrent.Executors;
43 import java.util.concurrent.FutureTask;
44 
45 /**
46  * FeatureProvider for the refactored search code.
47  */
48 public class SearchFeatureProviderImpl implements SearchFeatureProvider {
49 
50     private static final String TAG = "SearchFeatureProvider";
51 
52     private DatabaseIndexingManager mDatabaseIndexingManager;
53     private ExecutorService mExecutorService;
54     private SiteMapManager mSiteMapManager;
55 
56     @Override
getSearchResultLoader(Context context, String query)57     public SearchResultLoader getSearchResultLoader(Context context, String query) {
58         return new SearchResultLoader(context, cleanQuery(query));
59     }
60 
61     @Override
getSearchQueryTasks(Context context, String query)62     public List<SearchQueryTask> getSearchQueryTasks(Context context, String query) {
63         final List<SearchQueryTask> tasks = new ArrayList<>();
64         final String cleanQuery = cleanQuery(query);
65         tasks.add(DatabaseResultTask.newTask(context, getSiteMapManager(), cleanQuery));
66         tasks.add(InstalledAppResultTask.newTask(context, getSiteMapManager(), cleanQuery));
67         tasks.add(AccessibilityServiceResultTask.newTask(context, getSiteMapManager(), cleanQuery));
68         tasks.add(InputDeviceResultTask.newTask(context, getSiteMapManager(), cleanQuery));
69         return tasks;
70     }
71 
72     @Override
getSavedQueryLoader(Context context)73     public SavedQueryLoader getSavedQueryLoader(Context context) {
74         return new SavedQueryLoader(context);
75     }
76 
77     @Override
getIndexingManager(Context context)78     public DatabaseIndexingManager getIndexingManager(Context context) {
79         if (mDatabaseIndexingManager == null) {
80             mDatabaseIndexingManager = new DatabaseIndexingManager(context.getApplicationContext());
81         }
82         return mDatabaseIndexingManager;
83     }
84 
85     @Override
getSiteMapManager()86     public SiteMapManager getSiteMapManager() {
87         if (mSiteMapManager == null) {
88             mSiteMapManager = new SiteMapManager();
89         }
90         return mSiteMapManager;
91     }
92 
93     @Override
isIndexingComplete(Context context)94     public boolean isIndexingComplete(Context context) {
95         return getIndexingManager(context).isIndexingComplete();
96     }
97 
98     @Override
initFeedbackButton()99     public void initFeedbackButton() {
100     }
101 
102     @Override
showFeedbackButton(SearchFragment fragment, View root)103     public void showFeedbackButton(SearchFragment fragment, View root) {
104     }
105 
106     @Override
hideFeedbackButton(View root)107     public void hideFeedbackButton(View root) {
108     }
109 
110     @Override
searchResultClicked(Context context, String query, SearchResult searchResult)111     public void searchResultClicked(Context context, String query, SearchResult searchResult) {
112     }
113 
114     @Override
isSmartSearchRankingEnabled(Context context)115     public boolean isSmartSearchRankingEnabled(Context context) {
116         return false;
117     }
118 
119     @Override
smartSearchRankingTimeoutMs(Context context)120     public long smartSearchRankingTimeoutMs(Context context) {
121         return 300L;
122     }
123 
124     @Override
searchRankingWarmup(Context context)125     public void searchRankingWarmup(Context context) {
126     }
127 
128     @Override
getRankerTask(Context context, String query)129     public FutureTask<List<Pair<String, Float>>> getRankerTask(Context context, String query) {
130         return null;
131     }
132 
133     @Override
updateIndexAsync(Context context, IndexingCallback callback)134     public void updateIndexAsync(Context context, IndexingCallback callback) {
135         if (DEBUG) {
136             Log.d(TAG, "updating index async");
137         }
138         getIndexingManager(context).indexDatabase(callback);
139     }
140 
141     @Override
getExecutorService()142     public ExecutorService getExecutorService() {
143         if (mExecutorService == null) {
144             mExecutorService = Executors.newCachedThreadPool();
145         }
146         return mExecutorService;
147     }
148 
149     /**
150      * A generic method to make the query suitable for searching the database.
151      *
152      * @return the cleaned query string
153      */
154     @VisibleForTesting
cleanQuery(String query)155     String cleanQuery(String query) {
156         if (TextUtils.isEmpty(query)) {
157             return null;
158         }
159         if (Locale.getDefault().equals(Locale.JAPAN)) {
160             query = IndexData.normalizeJapaneseString(query);
161         }
162         return query.trim();
163     }
164 }
165