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 package com.android.voicemail.impl.transcribe; 17 18 import android.annotation.TargetApi; 19 import android.content.ContentResolver; 20 import android.content.ContentUris; 21 import android.content.ContentValues; 22 import android.content.Context; 23 import android.database.Cursor; 24 import android.net.Uri; 25 import android.os.Build; 26 import android.provider.VoicemailContract.Voicemails; 27 import android.support.annotation.VisibleForTesting; 28 import android.support.annotation.WorkerThread; 29 import android.util.Pair; 30 import com.android.dialer.common.Assert; 31 import com.android.dialer.common.LogUtil; 32 import com.android.dialer.compat.android.provider.VoicemailCompat; 33 import java.util.ArrayList; 34 import java.util.List; 35 36 /** Helper class for reading and writing transcription data in the database */ 37 @TargetApi(Build.VERSION_CODES.O) 38 public class TranscriptionDbHelper { 39 @VisibleForTesting 40 static final String[] PROJECTION = 41 new String[] { 42 Voicemails._ID, // 0 43 Voicemails.TRANSCRIPTION, // 1 44 VoicemailCompat.TRANSCRIPTION_STATE // 2 45 }; 46 47 static final int ID = 0; 48 static final int TRANSCRIPTION = 1; 49 static final int TRANSCRIPTION_STATE = 2; 50 51 private final ContentResolver contentResolver; 52 private final Uri uri; 53 54 TranscriptionDbHelper(Context context, Uri uri) { 55 Assert.isNotNull(uri); 56 this.contentResolver = context.getContentResolver(); 57 this.uri = uri; 58 } 59 60 TranscriptionDbHelper(Context context) { 61 this(context, Voicemails.buildSourceUri(context.getPackageName())); 62 } 63 64 @WorkerThread 65 Pair<String, Integer> getTranscriptionAndState() { 66 Assert.checkState(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O); 67 Assert.isWorkerThread(); 68 try (Cursor cursor = contentResolver.query(uri, PROJECTION, null, null, null)) { 69 if (cursor == null) { 70 LogUtil.e("TranscriptionDbHelper.getTranscriptionAndState", "query failed."); 71 return null; 72 } 73 74 if (cursor.moveToFirst()) { 75 String transcription = cursor.getString(TRANSCRIPTION); 76 int transcriptionState = cursor.getInt(TRANSCRIPTION_STATE); 77 return new Pair<>(transcription, transcriptionState); 78 } 79 } 80 LogUtil.i("TranscriptionDbHelper.getTranscriptionAndState", "query returned no results"); 81 return null; 82 } 83 84 @WorkerThread 85 List<Uri> getUntranscribedVoicemails() { 86 Assert.checkState(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O); 87 Assert.isWorkerThread(); 88 List<Uri> untranscribed = new ArrayList<>(); 89 String whereClause = 90 Voicemails.TRANSCRIPTION + " is NULL AND " + VoicemailCompat.TRANSCRIPTION_STATE + "=?"; 91 String[] whereArgs = {String.valueOf(VoicemailCompat.TRANSCRIPTION_NOT_STARTED)}; 92 try (Cursor cursor = contentResolver.query(uri, PROJECTION, whereClause, whereArgs, null)) { 93 if (cursor == null) { 94 LogUtil.e("TranscriptionDbHelper.getUntranscribedVoicemails", "query failed."); 95 } else { 96 while (cursor.moveToNext()) { 97 untranscribed.add(ContentUris.withAppendedId(uri, cursor.getLong(ID))); 98 } 99 } 100 } 101 return untranscribed; 102 } 103 104 @WorkerThread 105 List<Uri> getTranscribingVoicemails() { 106 Assert.checkState(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O); 107 Assert.isWorkerThread(); 108 List<Uri> inProgress = new ArrayList<>(); 109 String whereClause = VoicemailCompat.TRANSCRIPTION_STATE + "=?"; 110 String[] whereArgs = {String.valueOf(VoicemailCompat.TRANSCRIPTION_IN_PROGRESS)}; 111 try (Cursor cursor = contentResolver.query(uri, PROJECTION, whereClause, whereArgs, null)) { 112 if (cursor == null) { 113 LogUtil.e("TranscriptionDbHelper.getTranscribingVoicemails", "query failed."); 114 } else { 115 while (cursor.moveToNext()) { 116 inProgress.add(ContentUris.withAppendedId(uri, cursor.getLong(ID))); 117 } 118 } 119 } 120 return inProgress; 121 } 122 123 @WorkerThread 124 void setTranscriptionState(int transcriptionState) { 125 Assert.isWorkerThread(); 126 LogUtil.i( 127 "TranscriptionDbHelper.setTranscriptionState", 128 "uri: " + uri + ", state: " + transcriptionState); 129 ContentValues values = new ContentValues(); 130 values.put(VoicemailCompat.TRANSCRIPTION_STATE, transcriptionState); 131 updateDatabase(values); 132 } 133 134 @WorkerThread 135 void setTranscriptionAndState(String transcription, int transcriptionState) { 136 Assert.isWorkerThread(); 137 LogUtil.i( 138 "TranscriptionDbHelper.setTranscriptionAndState", 139 "uri: " + uri + ", state: " + transcriptionState); 140 ContentValues values = new ContentValues(); 141 values.put(Voicemails.TRANSCRIPTION, transcription); 142 values.put(VoicemailCompat.TRANSCRIPTION_STATE, transcriptionState); 143 updateDatabase(values); 144 } 145 146 private void updateDatabase(ContentValues values) { 147 int updatedCount = contentResolver.update(uri, values, null, null); 148 if (updatedCount != 1) { 149 LogUtil.e( 150 "TranscriptionDbHelper.updateDatabase", 151 "Wrong row count, should have updated 1 row, was: " + updatedCount); 152 } 153 } 154 } 155