LocalSearchProvider.java revision 919e1ed7e914029a1a0054237d86dc7b19ced898
1/* 2 * Copyright (C) 2015 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 17package com.android.tv.search; 18 19import android.app.SearchManager; 20import android.content.ContentProvider; 21import android.content.ContentValues; 22import android.database.Cursor; 23import android.database.MatrixCursor; 24import android.net.Uri; 25import android.os.SystemClock; 26import android.text.TextUtils; 27import android.util.Log; 28 29import com.android.tv.util.PermissionUtils; 30 31import java.util.ArrayList; 32import java.util.Arrays; 33import java.util.List; 34 35public class LocalSearchProvider extends ContentProvider { 36 private static final String TAG = "LocalSearchProvider"; 37 private static final boolean DEBUG = false; 38 39 public static final int PROGRESS_PERCENTAGE_HIDE = -1; 40 41 // TODO: Remove this once added to the SearchManager. 42 private static final String SUGGEST_COLUMN_PROGRESS_BAR_PERCENTAGE = "progress_bar_percentage"; 43 44 private static final String[] SEARCHABLE_COLUMNS = new String[] { 45 SearchManager.SUGGEST_COLUMN_TEXT_1, 46 SearchManager.SUGGEST_COLUMN_TEXT_2, 47 SearchManager.SUGGEST_COLUMN_RESULT_CARD_IMAGE, 48 SearchManager.SUGGEST_COLUMN_INTENT_ACTION, 49 SearchManager.SUGGEST_COLUMN_INTENT_DATA, 50 SearchManager.SUGGEST_COLUMN_CONTENT_TYPE, 51 SearchManager.SUGGEST_COLUMN_IS_LIVE, 52 SearchManager.SUGGEST_COLUMN_VIDEO_WIDTH, 53 SearchManager.SUGGEST_COLUMN_VIDEO_HEIGHT, 54 SearchManager.SUGGEST_COLUMN_DURATION, 55 SUGGEST_COLUMN_PROGRESS_BAR_PERCENTAGE 56 }; 57 58 private static final String EXPECTED_PATH_PREFIX = "/" + SearchManager.SUGGEST_URI_PATH_QUERY; 59 // The launcher passes 10 as a 'limit' parameter by default. 60 private static final int DEFAULT_SEARCH_LIMIT = 10; 61 62 private static final String NO_LIVE_CONTENTS = "0"; 63 private static final String LIVE_CONTENTS = "1"; 64 65 static final String SUGGEST_PARAMETER_ACTION = "action"; 66 static final int DEFAULT_SEARCH_ACTION = SearchInterface.ACTION_TYPE_AMBIGUOUS; 67 68 @Override 69 public boolean onCreate() { 70 return true; 71 } 72 73 @Override 74 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 75 String sortOrder) { 76 if (DEBUG) { 77 Log.d(TAG, "query(" + uri + ", " + Arrays.toString(projection) + ", " + selection + ", " 78 + Arrays.toString(selectionArgs) + ", " + sortOrder + ")"); 79 } 80 long time = SystemClock.elapsedRealtime(); 81 SearchInterface search; 82 if (PermissionUtils.hasAccessAllEpg(getContext())) { 83 if (DEBUG) Log.d(TAG, "Performing TV Provider search."); 84 search = new TvProviderSearch(getContext()); 85 } else { 86 if (DEBUG) Log.d(TAG, "Performing Data Manager search."); 87 search = new DataManagerSearch(getContext()); 88 } 89 String query = uri.getLastPathSegment(); 90 int limit = DEFAULT_SEARCH_LIMIT; 91 int action = DEFAULT_SEARCH_ACTION; 92 try { 93 limit = Integer.parseInt(uri.getQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT)); 94 action = Integer.parseInt(uri.getQueryParameter(SUGGEST_PARAMETER_ACTION)); 95 } catch (NumberFormatException | UnsupportedOperationException e) { 96 // Ignore the exceptions 97 } 98 List<SearchResult> results = new ArrayList<>(); 99 if (!TextUtils.isEmpty(query)) { 100 results.addAll(search.search(query, limit, action)); 101 } 102 Cursor c = createSuggestionsCursor(results); 103 if (DEBUG) Log.d(TAG, "Elapsed time: " + (SystemClock.elapsedRealtime() - time) + "(msec)"); 104 return c; 105 } 106 107 private Cursor createSuggestionsCursor(List<SearchResult> results) { 108 MatrixCursor cursor = new MatrixCursor(SEARCHABLE_COLUMNS, results.size()); 109 List<String> row = new ArrayList<>(SEARCHABLE_COLUMNS.length); 110 111 for (SearchResult result : results) { 112 row.clear(); 113 row.add(result.title); 114 row.add(result.description); 115 row.add(result.imageUri); 116 row.add(result.intentAction); 117 row.add(result.intentData); 118 row.add(result.contentType); 119 row.add(result.isLive ? LIVE_CONTENTS : NO_LIVE_CONTENTS); 120 row.add(result.videoWidth == 0 ? null : String.valueOf(result.videoWidth)); 121 row.add(result.videoHeight == 0 ? null : String.valueOf(result.videoHeight)); 122 row.add(result.duration == 0 ? null : String.valueOf(result.duration)); 123 row.add(String.valueOf(result.progressPercentage)); 124 cursor.addRow(row); 125 } 126 return cursor; 127 } 128 129 @Override 130 public String getType(Uri uri) { 131 if (!checkUriCorrect(uri)) return null; 132 return SearchManager.SUGGEST_MIME_TYPE; 133 } 134 135 private static boolean checkUriCorrect(Uri uri) { 136 return uri != null && uri.getPath().startsWith(EXPECTED_PATH_PREFIX); 137 } 138 139 @Override 140 public Uri insert(Uri uri, ContentValues values) { 141 throw new UnsupportedOperationException(); 142 } 143 144 @Override 145 public int delete(Uri uri, String selection, String[] selectionArgs) { 146 throw new UnsupportedOperationException(); 147 } 148 149 @Override 150 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 151 throw new UnsupportedOperationException(); 152 } 153 154 /** 155 * A placeholder to a search result. 156 */ 157 public static class SearchResult { 158 public long channelId; 159 public String channelNumber; 160 public String title; 161 public String description; 162 public String imageUri; 163 public String intentAction; 164 public String intentData; 165 public String contentType; 166 public boolean isLive; 167 public int videoWidth; 168 public int videoHeight; 169 public long duration; 170 public int progressPercentage; 171 172 @Override 173 public String toString() { 174 return "channelId: " + channelId + 175 ", channelNumber: " + channelNumber + 176 ", title: " + title; 177 } 178 } 179}