• 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 
17 package com.android.car.messenger.impl.datamodels.util;
18 
19 import static android.provider.BaseColumns._ID;
20 import static android.provider.Telephony.BaseMmsColumns.CONTENT_TYPE;
21 
22 import android.content.Context;
23 import android.database.Cursor;
24 import android.net.Uri;
25 import android.provider.Telephony;
26 import android.provider.Telephony.Mms.Addr;
27 import android.provider.Telephony.Mms.Part;
28 import android.provider.Telephony.Sms;
29 
30 import androidx.annotation.NonNull;
31 
32 import java.text.MessageFormat;
33 import java.time.Instant;
34 
35 /** MMS Utils for parsing MMS Telephony Content */
36 class MmsUtils {
37 
38     @NonNull public static final String FORMAT_CONTENT_MMS_PART = "content://mms/{0}/part";
39     @NonNull public static final String FORMAT_CONTENT_MMS_ADDR = "content://mms/{0}/addr";
40     @NonNull public static final String FORMAT_TYPE_AND_MSG_ID = "type={0} AND msg_id={1}";
41 
42     /** MMS text messages come with extra characters and new lines that need to be removed */
43     @NonNull private static final String REPLACE_CHARS = "\r\n";
44 
MmsUtils()45     private MmsUtils() {}
46 
47     @NonNull static final String MMS_CONTENT_TYPE = "application/vnd.wap.multipart.related";
48     private static final int ORIGINATOR_ADDRESS_TYPE = 137;
49 
50     /** Returns true, if item on cursor position is an MMS message */
isMms(@onNull Cursor cursor)51     static Boolean isMms(@NonNull Cursor cursor) {
52         String contentType = cursor.getString(cursor.getColumnIndex(CONTENT_TYPE));
53         return MMS_CONTENT_TYPE.equals(contentType);
54     }
55 
56     /**
57      * Returns the parsed result as {link @MmsSmsMessage}
58      *
59      * @throws IllegalArgumentException if desired columns are missing.
60      * @see CursorUtils#CONTENT_CONVERSATION_PROJECTION
61      */
62     @NonNull
parseMms(@onNull Context context, @NonNull Cursor cursor)63     static MmsSmsMessage parseMms(@NonNull Context context, @NonNull Cursor cursor) {
64         MmsSmsMessage message = new MmsSmsMessage();
65         message.mId = cursor.getString(cursor.getColumnIndex(_ID));
66         message.mThreadId = cursor.getInt(cursor.getColumnIndex(Sms.THREAD_ID));
67         message.mType = cursor.getInt(cursor.getColumnIndex(Telephony.Mms.MESSAGE_BOX));
68         message.mSubscriptionId = cursor.getInt(cursor.getColumnIndex(Sms.SUBSCRIPTION_ID));
69         message.mDate = Instant.ofEpochSecond(cursor.getLong(cursor.getColumnIndex(Sms.DATE)));
70         message.mRead = cursor.getInt(cursor.getColumnIndex(Sms.READ)) == 1;
71         message.mPhoneNumber = getOriginator(context, message.mId);
72         message.mBody = getMmsBody(context, message.mId);
73         return message;
74     }
75 
getMmsBody(@onNull Context context, @NonNull String id)76     private static String getMmsBody(@NonNull Context context, @NonNull String id) {
77         String uriStr = MessageFormat.format(FORMAT_CONTENT_MMS_PART, id);
78         Uri uriAddress = Uri.parse(uriStr);
79         Cursor cursor = CursorUtils.simpleQuery(context, uriAddress);
80         StringBuilder stringBuilder = new StringBuilder();
81         while (cursor != null && cursor.moveToNext()) {
82             stringBuilder.append(cursor.getString(cursor.getColumnIndex(Part.TEXT)));
83             stringBuilder.append(" ");
84         }
85         return stringBuilder.toString().replace(REPLACE_CHARS, "");
86     }
87 
88     @NonNull
getOriginator(@onNull Context context, @NonNull String id)89     private static String getOriginator(@NonNull Context context, @NonNull String id) {
90         String selection =
91                 MessageFormat.format(FORMAT_TYPE_AND_MSG_ID, ORIGINATOR_ADDRESS_TYPE, id);
92         String uriStr = MessageFormat.format(FORMAT_CONTENT_MMS_ADDR, id);
93         Cursor cursor = CursorUtils.simpleQueryWithSelection(context, Uri.parse(uriStr), selection);
94         String phoneNum = "";
95         if (cursor != null && cursor.moveToFirst()) {
96             cursor.moveToFirst();
97             phoneNum = cursor.getString(cursor.getColumnIndex(Addr.ADDRESS));
98             cursor.close();
99         }
100         return phoneNum;
101     }
102 }
103