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.app.SearchManager 19 import android.database.AbstractCursor 20 import android.database.CursorIndexOutOfBoundsException 21 import kotlin.collections.ArrayList 22 23 class SuggestionCursorBackedCursor(private val mCursor: SuggestionCursor?) : AbstractCursor() { 24 private var mExtraColumns: ArrayList<String>? = null 25 26 @Override closenull27 override fun close() { 28 super.close() 29 mCursor?.close() 30 } 31 32 @Override getColumnNamesnull33 override fun getColumnNames(): Array<String> { 34 val extraColumns: Collection<String>? = mCursor?.extraColumns 35 return if (extraColumns != null) { 36 val allColumns: ArrayList<String> = ArrayList<String>(COLUMNS.size + extraColumns.size) 37 mExtraColumns = ArrayList<String>(extraColumns) 38 allColumns.addAll(COLUMNS.asList()) 39 mExtraColumns?.let { allColumns.addAll(it) } 40 allColumns.toArray(arrayOfNulls<String>(allColumns.size)) 41 } else { 42 COLUMNS 43 } 44 } 45 46 @Override getCountnull47 override fun getCount(): Int { 48 return mCursor!!.count 49 } 50 getnull51 private fun get(): SuggestionCursor? { 52 mCursor?.moveTo(position) 53 return mCursor 54 } 55 getExtranull56 private fun getExtra(columnIdx: Int): String? { 57 val extraColumn = columnIdx - COLUMNS.size 58 val extras: SuggestionExtras? = get()?.extras 59 return extras?.getExtra(mExtraColumns!!.get(extraColumn)) 60 } 61 62 @Override getIntnull63 override fun getInt(column: Int): Int { 64 return if (column == COLUMN_INDEX_ID) { 65 position 66 } else { 67 try { 68 getString(column)!!.toInt() 69 } catch (e: NumberFormatException) { 70 0 71 } 72 } 73 } 74 75 @Override getStringnull76 override fun getString(column: Int): String? { 77 return if (column < COLUMNS.size) { 78 when (column) { 79 COLUMN_INDEX_ID -> position.toString() 80 COLUMN_INDEX_TEXT1 -> get()?.suggestionText1 81 COLUMN_INDEX_TEXT2 -> get()?.suggestionText2 82 COLUMN_INDEX_TEXT2_URL -> get()?.suggestionText2Url 83 COLUMN_INDEX_ICON1 -> get()?.suggestionIcon1 84 COLUMN_INDEX_ICON2 -> get()?.suggestionIcon2 85 COLUMN_INDEX_INTENT_ACTION -> get()?.suggestionIntentAction 86 COLUMN_INDEX_INTENT_DATA -> get()?.suggestionIntentDataString 87 COLUMN_INDEX_INTENT_EXTRA_DATA -> get()?.suggestionIntentExtraData 88 COLUMN_INDEX_QUERY -> get()?.suggestionQuery 89 COLUMN_INDEX_FORMAT -> get()?.suggestionFormat 90 COLUMN_INDEX_SHORTCUT_ID -> get()?.shortcutId 91 COLUMN_INDEX_SPINNER_WHILE_REFRESHING -> get()?.isSpinnerWhileRefreshing.toString() 92 else -> 93 throw CursorIndexOutOfBoundsException( 94 "Requested column " + column + " of " + COLUMNS.size 95 ) 96 } 97 } else { 98 getExtra(column) 99 } 100 } 101 102 @Override getLongnull103 override fun getLong(column: Int): Long { 104 return try { 105 getString(column)!!.toLong() 106 } catch (e: NumberFormatException) { 107 0 108 } 109 } 110 111 @Override isNullnull112 override fun isNull(column: Int): Boolean { 113 return getString(column) == null 114 } 115 116 @Override getShortnull117 override fun getShort(column: Int): Short { 118 return try { 119 getString(column)!!.toShort() 120 } catch (e: NumberFormatException) { 121 0 122 } 123 } 124 125 @Override getDoublenull126 override fun getDouble(column: Int): Double { 127 return try { 128 getString(column)!!.toDouble() 129 } catch (e: NumberFormatException) { 130 0.0 131 } 132 } 133 134 @Override getFloatnull135 override fun getFloat(column: Int): Float { 136 return try { 137 getString(column)!!.toFloat() 138 } catch (e: NumberFormatException) { 139 0.0F 140 } 141 } 142 143 companion object { 144 // This array also used in CursorBackedSuggestionExtras to avoid duplication. 145 val COLUMNS = 146 arrayOf( 147 "_id", // 0, This will contain the row number. CursorAdapter, used by SuggestionsAdapter, 148 // used by SearchDialog, expects an _id column. 149 SearchManager.SUGGEST_COLUMN_TEXT_1, // 1 150 SearchManager.SUGGEST_COLUMN_TEXT_2, // 2 151 SearchManager.SUGGEST_COLUMN_TEXT_2_URL, // 3 152 SearchManager.SUGGEST_COLUMN_ICON_1, // 4 153 SearchManager.SUGGEST_COLUMN_ICON_2, // 5 154 SearchManager.SUGGEST_COLUMN_INTENT_ACTION, // 6 155 SearchManager.SUGGEST_COLUMN_INTENT_DATA, // 7 156 SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, // 8 157 SearchManager.SUGGEST_COLUMN_QUERY, // 9 158 SearchManager.SUGGEST_COLUMN_FORMAT, // 10 159 SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, // 11 160 SearchManager.SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING 161 ) 162 private const val COLUMN_INDEX_ID = 0 163 private const val COLUMN_INDEX_TEXT1 = 1 164 private const val COLUMN_INDEX_TEXT2 = 2 165 private const val COLUMN_INDEX_TEXT2_URL = 3 166 private const val COLUMN_INDEX_ICON1 = 4 167 private const val COLUMN_INDEX_ICON2 = 5 168 private const val COLUMN_INDEX_INTENT_ACTION = 6 169 private const val COLUMN_INDEX_INTENT_DATA = 7 170 private const val COLUMN_INDEX_INTENT_EXTRA_DATA = 8 171 private const val COLUMN_INDEX_QUERY = 9 172 private const val COLUMN_INDEX_FORMAT = 10 173 private const val COLUMN_INDEX_SHORTCUT_ID = 11 174 private const val COLUMN_INDEX_SPINNER_WHILE_REFRESHING = 12 175 } 176 } 177