1 /*
2  * Copyright (C) 2018 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 
17 package com.android.dialer.rtt;
18 
19 import android.content.ContentValues;
20 import android.content.Context;
21 import android.database.Cursor;
22 import android.support.annotation.WorkerThread;
23 import com.android.dialer.common.Assert;
24 import com.android.dialer.common.concurrent.DialerExecutorComponent;
25 import com.android.dialer.common.database.Selection;
26 import com.android.dialer.rtt.RttTranscriptContract.RttTranscriptColumn;
27 import com.google.common.collect.ImmutableSet;
28 import com.google.common.util.concurrent.ListenableFuture;
29 import com.google.protobuf.InvalidProtocolBufferException;
30 
31 /** Util class to save and load RTT transcript. */
32 public final class RttTranscriptUtil {
33 
getAvailableRttTranscriptIds( Context context, ImmutableSet<String> transcriptIds)34   public static ListenableFuture<ImmutableSet<String>> getAvailableRttTranscriptIds(
35       Context context, ImmutableSet<String> transcriptIds) {
36     return DialerExecutorComponent.get(context)
37         .backgroundExecutor()
38         .submit(() -> checkRttTranscriptAvailability(context, transcriptIds));
39   }
40 
41   @WorkerThread
checkRttTranscriptAvailability( Context context, ImmutableSet<String> transcriptIds)42   private static ImmutableSet<String> checkRttTranscriptAvailability(
43       Context context, ImmutableSet<String> transcriptIds) {
44     Assert.isWorkerThread();
45     RttTranscriptDatabaseHelper databaseHelper = new RttTranscriptDatabaseHelper(context);
46     ImmutableSet.Builder<String> builder = ImmutableSet.builder();
47     Selection selection =
48         Selection.builder()
49             .and(Selection.column(RttTranscriptColumn.TRANSCRIPT_ID).in(transcriptIds))
50             .build();
51 
52     try (Cursor cursor =
53         databaseHelper
54             .getReadableDatabase()
55             .query(
56                 RttTranscriptDatabaseHelper.TABLE,
57                 new String[] {RttTranscriptColumn.TRANSCRIPT_ID},
58                 selection.getSelection(),
59                 selection.getSelectionArgs(),
60                 null,
61                 null,
62                 null)) {
63       if (cursor != null) {
64         while (cursor.moveToNext()) {
65           builder.add(cursor.getString(0));
66         }
67       }
68     }
69     databaseHelper.close();
70     return builder.build();
71   }
72 
loadRttTranscript(Context context, String transcriptId)73   static ListenableFuture<RttTranscript> loadRttTranscript(Context context, String transcriptId) {
74     return DialerExecutorComponent.get(context)
75         .lightweightExecutor()
76         .submit(() -> getRttTranscript(context, transcriptId));
77   }
78 
79   @WorkerThread
getRttTranscript(Context context, String transcriptId)80   private static RttTranscript getRttTranscript(Context context, String transcriptId) {
81     Assert.isWorkerThread();
82     RttTranscriptDatabaseHelper databaseHelper = new RttTranscriptDatabaseHelper(context);
83     try (Cursor cursor =
84         databaseHelper
85             .getReadableDatabase()
86             .query(
87                 RttTranscriptDatabaseHelper.TABLE,
88                 new String[] {RttTranscriptColumn.TRANSCRIPT_DATA},
89                 RttTranscriptColumn.TRANSCRIPT_ID + " = ?",
90                 new String[] {transcriptId},
91                 null,
92                 null,
93                 null)) {
94       if (cursor != null && cursor.moveToFirst()) {
95         try {
96           return RttTranscript.parseFrom(cursor.getBlob(0));
97         } catch (InvalidProtocolBufferException e) {
98           throw new RuntimeException("Parse failed for RTT transcript", e);
99         }
100       } else {
101         return null;
102       }
103     } finally {
104       databaseHelper.close();
105     }
106   }
107 
saveRttTranscript( Context context, RttTranscript rttTranscript)108   public static ListenableFuture<Void> saveRttTranscript(
109       Context context, RttTranscript rttTranscript) {
110     return DialerExecutorComponent.get(context)
111         .backgroundExecutor()
112         .submit(
113             () -> {
114               save(context, rttTranscript);
115               return null;
116             });
117   }
118 
119   @WorkerThread
save(Context context, RttTranscript rttTranscript)120   private static void save(Context context, RttTranscript rttTranscript) {
121     Assert.isWorkerThread();
122     RttTranscriptDatabaseHelper databaseHelper = new RttTranscriptDatabaseHelper(context);
123     ContentValues value = new ContentValues();
124     value.put(RttTranscriptColumn.TRANSCRIPT_ID, rttTranscript.getId());
125     value.put(RttTranscriptColumn.TRANSCRIPT_DATA, rttTranscript.toByteArray());
126     long id =
127         databaseHelper.getWritableDatabase().insert(RttTranscriptDatabaseHelper.TABLE, null, value);
128     databaseHelper.close();
129     if (id < 0) {
130       throw new RuntimeException("Failed to save RTT transcript");
131     }
132   }
133 }
134