• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.car.messenger.impl.datamodels.util;
17 
18 import static android.provider.BaseColumns._ID;
19 import static android.provider.Telephony.BaseMmsColumns.CONTENT_TYPE;
20 import static android.provider.Telephony.BaseMmsColumns.MESSAGE_BOX;
21 import static android.provider.Telephony.MmsSms.CONTENT_CONVERSATIONS_URI;
22 import static android.provider.Telephony.TextBasedSmsColumns.ADDRESS;
23 import static android.provider.Telephony.TextBasedSmsColumns.BODY;
24 import static android.provider.Telephony.TextBasedSmsColumns.SUBSCRIPTION_ID;
25 import static android.provider.Telephony.TextBasedSmsColumns.THREAD_ID;
26 import static android.provider.Telephony.TextBasedSmsColumns.TYPE;
27 import static android.provider.Telephony.ThreadsColumns.DATE;
28 import static android.provider.Telephony.ThreadsColumns.READ;
29 import static android.provider.Telephony.ThreadsColumns.RECIPIENT_IDS;
30 
31 import android.content.ContentResolver;
32 import android.content.Context;
33 import android.database.Cursor;
34 import android.net.Uri;
35 import android.provider.Telephony;
36 
37 import androidx.annotation.NonNull;
38 import androidx.annotation.Nullable;
39 
40 import com.android.car.messenger.core.interfaces.AppFactory;
41 
42 /** Cursor Utils to get quick cursor or uri telephony information */
43 public class CursorUtils {
CursorUtils()44     private CursorUtils() {}
45     // This URI provides all the metadata for a thread.
46     // Appending simple=true is important to get the recipient_ids for the conversation.
47     @NonNull
48     public static final Uri THREAD_INFO_URI =
49             CONTENT_CONVERSATIONS_URI.buildUpon().appendQueryParameter("simple", "true").build();
50 
51     @NonNull protected static final String[] THREAD_INFO_PROJECTION = {_ID, RECIPIENT_IDS, READ};
52 
53     @NonNull
54     protected static final String[] CONTENT_CONVERSATION_PROJECTION = {
55         _ID, TYPE, DATE, READ, CONTENT_TYPE, BODY, ADDRESS, THREAD_ID, SUBSCRIPTION_ID, MESSAGE_BOX
56     };
57 
58     /** Provides the default sort order for items in database. Default is DESC order by Date. */
59     @NonNull
60     public static final String DEFAULT_SORT_ORDER = Telephony.TextBasedSmsColumns.DATE + " DESC";
61 
62     /**
63      * Get simplified thread cursor with metadata information on the thread, such as recipient ids
64      */
65     @Nullable
getThreadCursor(@onNull String threadId)66     public static Cursor getThreadCursor(@NonNull String threadId) {
67         Context context = AppFactory.get().getContext();
68         ContentResolver contentResolver = context.getContentResolver();
69         return contentResolver.query(
70                 THREAD_INFO_URI,
71                 THREAD_INFO_PROJECTION,
72                 _ID + "=" + threadId,
73                 /* selectionArgs= */ null,
74                 DEFAULT_SORT_ORDER);
75     }
76 
77     /**
78      * Get the message cursor in descending order for
79      *
80      * @param conversationId The conversation or thread id for the conversation
81      * @param limit The maximum number of message rows to fetch
82      * @param offset The starting point in timestamp in millisecond to fetch for data
83      */
84     @Nullable
getMessagesCursor(@onNull String conversationId, int limit, long offset)85     public static Cursor getMessagesCursor(@NonNull String conversationId, int limit, long offset) {
86         Context context = AppFactory.get().getContext();
87         ContentResolver contentResolver = context.getContentResolver();
88         return contentResolver.query(
89                 getConversationUri(conversationId),
90                 CONTENT_CONVERSATION_PROJECTION,
91                 DATE + " > " + offset,
92                 /* selectionArgs= */ null,
93                 DEFAULT_SORT_ORDER + " LIMIT " + limit);
94     }
95 
96     /** Gets the Conversation Uri for the Conversation with specified conversationId */
97     @NonNull
getConversationUri(@onNull String conversationId)98     public static Uri getConversationUri(@NonNull String conversationId) {
99         return CONTENT_CONVERSATIONS_URI.buildUpon().appendPath(conversationId).build();
100     }
101 
102     /** Returns a cursor query with the uri provided, with no filtering or projection */
103     @Nullable
simpleQuery(@onNull Context context, @NonNull Uri uri)104     public static Cursor simpleQuery(@NonNull Context context, @NonNull Uri uri) {
105         return context.getContentResolver().query(uri, null, null, null, null);
106     }
107 
108     /** Returns a cursor query given a uri and projection */
109     @Nullable
simpleQueryWithProjection( @onNull Context context, @NonNull Uri uri, @Nullable String[] projection)110     public static Cursor simpleQueryWithProjection(
111             @NonNull Context context, @NonNull Uri uri, @Nullable String[] projection) {
112         return context.getContentResolver().query(uri, projection, null, null, null);
113     }
114 
115     /** Returns a cursor query given a uri and selection */
116     @Nullable
simpleQueryWithSelection( @onNull Context context, @NonNull Uri uri, @Nullable String selection)117     public static Cursor simpleQueryWithSelection(
118             @NonNull Context context, @NonNull Uri uri, @Nullable String selection) {
119         return context.getContentResolver().query(uri, null, selection, null, null);
120     }
121 }
122