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.database.Cursor
19 import android.util.Log
20 import kotlin.Array
21 import kotlin.collections.ArrayList
22 import kotlin.collections.HashSet
23 
24 /** SuggestionExtras taking values from the extra columns in a suggestion cursor. */
25 class CursorBackedSuggestionExtras
26 private constructor(cursor: Cursor?, position: Int, extraColumns: List<String>) :
27   AbstractSuggestionExtras(null) {
28   companion object {
29     private const val TAG = "QSB.CursorBackedSuggestionExtras"
30     private val DEFAULT_COLUMNS: HashSet<String> = HashSet<String>()
31     @JvmStatic
createExtrasIfNecessarynull32     fun createExtrasIfNecessary(cursor: Cursor?, position: Int): CursorBackedSuggestionExtras? {
33       val extraColumns: List<String>? =
34         CursorBackedSuggestionExtras.Companion.getExtraColumns(cursor)
35       return if (extraColumns != null) {
36         CursorBackedSuggestionExtras(cursor, position, extraColumns)
37       } else {
38         null
39       }
40     }
41 
42     @JvmStatic
getCursorColumnsnull43     fun getCursorColumns(cursor: Cursor?): Array<String>? {
44       return try {
45         cursor?.getColumnNames()
46       } catch (ex: RuntimeException) {
47         // all operations on cross-process cursors can throw random exceptions
48         Log.e(CursorBackedSuggestionExtras.Companion.TAG, "getColumnNames() failed, ", ex)
49         null
50       }
51     }
52 
cursorContainsExtrasnull53     fun cursorContainsExtras(cursor: Cursor?): Boolean {
54       val columns: Array<String>? = CursorBackedSuggestionExtras.Companion.getCursorColumns(cursor)
55       if (columns != null) {
56         for (cursorColumn in columns) {
57           if (!CursorBackedSuggestionExtras.Companion.DEFAULT_COLUMNS.contains(cursorColumn)) {
58             return true
59           }
60         }
61       }
62       return false
63     }
64 
65     @JvmStatic
getExtraColumnsnull66     fun getExtraColumns(cursor: Cursor?): List<String>? {
67       val columns: Array<String> =
68         CursorBackedSuggestionExtras.Companion.getCursorColumns(cursor) ?: return null
69       var extraColumns: ArrayList<String>? = null
70       for (cursorColumn in columns) {
71         if (!CursorBackedSuggestionExtras.Companion.DEFAULT_COLUMNS.contains(cursorColumn)) {
72           if (extraColumns == null) {
73             extraColumns = arrayListOf<String>()
74           }
75           extraColumns.add(cursorColumn)
76         }
77       }
78       return extraColumns
79     }
80 
81     init {
82       CursorBackedSuggestionExtras.Companion.DEFAULT_COLUMNS.addAll(
83         SuggestionCursorBackedCursor.COLUMNS.asList()
84       )
85     }
86   }
87 
88   private val mCursor: Cursor?
89   private val mCursorPosition: Int
90   private val mExtraColumns: List<String>
91   @Override
doGetExtranull92   override fun doGetExtra(columnName: String?): String? {
93     return try {
94       mCursor?.moveToPosition(mCursorPosition)
95       val columnIdx: Int = mCursor!!.getColumnIndex(columnName)
96       if (columnIdx < 0) null else mCursor.getString(columnIdx)
97     } catch (ex: RuntimeException) {
98       // all operations on cross-process cursors can throw random exceptions
99       Log.e(CursorBackedSuggestionExtras.Companion.TAG, "getExtra($columnName) failed, ", ex)
100       null
101     }
102   }
103 
104   @Override
doGetExtraColumnNamesnull105   public override fun doGetExtraColumnNames(): List<String> {
106     return mExtraColumns
107   }
108 
109   init {
110     mCursor = cursor
111     mCursorPosition = position
112     mExtraColumns = extraColumns
113   }
114 }
115