1 /* 2 * Copyright (C) 2020 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.cts.mockspellchecker 17 18 import android.content.ContentProvider 19 import android.content.ContentResolver 20 import android.content.ContentValues 21 import android.content.Context 22 import android.database.Cursor 23 import android.database.MatrixCursor 24 import android.net.Uri 25 import android.util.Base64 26 27 private const val PREFS_FILE_NAME = "prefs.xml" 28 private const val COLUMN_NAME = "value" 29 30 /** 31 * ContentProvider to access MockSpellChecker's shared preferences. 32 * 33 * <p>Please use the companion object methods to interact with this ContentProvider. The companion 34 * object methods can be used from other processes. 35 * 36 * <p>This class supports ByteArray value only. 37 */ 38 class SharedPrefsProvider : ContentProvider() { 39 <lambda>null40 override fun onCreate(): Boolean = withLog("SharedPrefsProvider.onCreate") { true } 41 getTypenull42 override fun getType(uri: Uri): String? = null 43 44 override fun query( 45 uri: Uri, 46 projection: Array<String>?, 47 selection: String?, 48 selectionArgs: Array<String>?, 49 sortOrder: String? 50 ): Cursor? = withLog("SharedPrefsProvider.query: $uri") { 51 val context = context ?: return null 52 val prefs = getSharedPreferences(context) 53 val bytes = Base64.decode(prefs.getString(uri.path, ""), Base64.DEFAULT) 54 val cursor = MatrixCursor(arrayOf(COLUMN_NAME)) 55 cursor.addRow(arrayOf(bytes)) 56 return cursor 57 } 58 insertnull59 override fun insert(uri: Uri, values: ContentValues?): Uri? = 60 withLog("SharedPrefsProvider.insert: $uri") { null } 61 updatenull62 override fun update( 63 uri: Uri, 64 values: ContentValues?, 65 selection: String?, 66 selectionArgs: Array<String>? 67 ): Int = withLog("SharedPrefsProvider.update: $uri") { 68 val context = context ?: return 0 69 if (values == null) return 0 70 val prefs = getSharedPreferences(context) 71 val bytes = values.getAsByteArray(COLUMN_NAME) 72 val str = Base64.encodeToString(bytes, Base64.DEFAULT) 73 prefs.edit().putString(uri.path, str).apply() 74 return 1 75 } 76 deletenull77 override fun delete( 78 uri: Uri, 79 selection: String?, 80 selectionArgs: Array<String>? 81 ): Int = withLog("SharedPrefsProvider.delete: $uri") { 82 val context = context ?: return 0 83 val prefs = getSharedPreferences(context) 84 prefs.edit().remove(uri.path).apply() 85 return 1 86 } 87 getSharedPreferencesnull88 private fun getSharedPreferences(context: Context) = 89 context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE) 90 91 companion object { 92 /** Returns the data for the key. */ 93 fun get(resolver: ContentResolver, key: String): ByteArray { 94 val cursor = resolver.query(uriFor(key), arrayOf(COLUMN_NAME), null, null) 95 return if (cursor != null && cursor.moveToNext()) { 96 cursor.getBlob(0) 97 } else { 98 ByteArray(0) 99 } 100 } 101 102 /** Stores the data for the key. */ 103 fun put(resolver: ContentResolver, key: String, value: ByteArray) { 104 val values = ContentValues() 105 values.put(COLUMN_NAME, value) 106 resolver.update(uriFor(key), values, null) 107 } 108 109 /** Deletes the data for the key. */ 110 fun delete(resolver: ContentResolver, key: String) { 111 resolver.delete(uriFor(key), null) 112 } 113 114 private fun uriFor(key: String): Uri = Uri.parse("content://$AUTHORITY/$key") 115 } 116 } 117