• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.telephony.common;
18 
19 import android.content.Context;
20 import android.database.Cursor;
21 import android.provider.CallLog;
22 import android.text.TextUtils;
23 
24 import androidx.annotation.NonNull;
25 
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Objects;
30 
31 /**
32  * Entity class for call logs of a phone number. This call log may contains multiple call
33  * records.
34  */
35 public class PhoneCallLog {
36     private static final String TAG = "CD.PhoneCallLog";
37 
38     /** Call log record. */
39     public static class Record implements Comparable<Record> {
40         private final long mCallEndTimestamp;
41         private final int mCallType;
42 
Record(long callEndTimestamp, int callType)43         public Record(long callEndTimestamp, int callType) {
44             mCallEndTimestamp = callEndTimestamp;
45             mCallType = callType;
46         }
47 
48         /** Returns the timestamp on when the call occured, in milliseconds since the epoch */
getCallEndTimestamp()49         public long getCallEndTimestamp() {
50             return mCallEndTimestamp;
51         }
52 
53         /**
54          * Returns the type of this record. For example, missed call, outbound call. Allowed values
55          * are defined in {@link CallLog.Calls#TYPE}.
56          *
57          * @see CallLog.Calls#TYPE
58          */
getCallType()59         public int getCallType() {
60             return mCallType;
61         }
62 
63         /** Phone call records are sort in reverse chronological order. */
64         @Override
compareTo(Record otherRecord)65         public int compareTo(Record otherRecord) {
66             return (int) (otherRecord.mCallEndTimestamp - mCallEndTimestamp);
67         }
68     }
69 
70     private long mId;
71     private String mPhoneNumberString;
72     private I18nPhoneNumberWrapper mI18nPhoneNumberWrapper;
73     private String mAccountName;
74     private List<Record> mCallRecords = new ArrayList<>();
75 
76     /**
77      * Creates a {@link PhoneCallLog} from a {@link Cursor}.
78      */
fromCursor(Context context, Cursor cursor)79     public static PhoneCallLog fromCursor(Context context, Cursor cursor) {
80         int idColumn = cursor.getColumnIndex(CallLog.Calls._ID);
81         int numberColumn = cursor.getColumnIndex(CallLog.Calls.NUMBER);
82         int dateColumn = cursor.getColumnIndex(CallLog.Calls.DATE);
83         int callTypeColumn = cursor.getColumnIndex(CallLog.Calls.TYPE);
84         int accountNameColumn = cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID);
85 
86         PhoneCallLog phoneCallLog = new PhoneCallLog();
87         phoneCallLog.mId = cursor.getLong(idColumn);
88         phoneCallLog.mPhoneNumberString = cursor.getString(numberColumn);
89         phoneCallLog.mI18nPhoneNumberWrapper = I18nPhoneNumberWrapper.Factory.INSTANCE.get(context,
90                 phoneCallLog.mPhoneNumberString);
91         Record record = new Record(cursor.getLong(dateColumn), cursor.getInt(callTypeColumn));
92         phoneCallLog.mCallRecords.add(record);
93         phoneCallLog.mAccountName = cursor.getString(accountNameColumn);
94         return phoneCallLog;
95     }
96 
97     /** Returns the phone number of this log. */
getPhoneNumberString()98     public String getPhoneNumberString() {
99         return mPhoneNumberString;
100     }
101 
102     /**
103      * Returns the account name that this call log belongs to. For call logs from Bluetooth device,
104      * account name is the same as Bluetooth address.
105      */
getAccountName()106     public String getAccountName() {
107         return mAccountName;
108     }
109 
110     /** Returns the id of this log. */
getPhoneLogId()111     public long getPhoneLogId() {
112         return mId;
113     }
114 
115     /**
116      * Returns the last call end timestamp of this number. Returns -1 if there's no call log
117      * records.
118      */
getLastCallEndTimestamp()119     public long getLastCallEndTimestamp() {
120         if (!mCallRecords.isEmpty()) {
121             return mCallRecords.get(0).getCallEndTimestamp();
122         }
123         return -1;
124     }
125 
126     /**
127      * Returns a copy of records from the phone number. Logs are sorted from most recent to least
128      * recent call end time.
129      */
getAllCallRecords()130     public List<Record> getAllCallRecords() {
131         return new ArrayList<>(mCallRecords);
132     }
133 
134     /**
135      * Merges all call records with this call log's call records if they are representing the same
136      * phone number.
137      */
merge(@onNull PhoneCallLog phoneCallLog)138     public boolean merge(@NonNull PhoneCallLog phoneCallLog) {
139         if (equals(phoneCallLog)) {
140             mCallRecords.addAll(phoneCallLog.mCallRecords);
141             Collections.sort(mCallRecords);
142             return true;
143         }
144         return false;
145     }
146 
147     @Override
equals(Object object)148     public boolean equals(Object object) {
149         if (object instanceof PhoneCallLog) {
150             // We compare the ids when the phone number string is empty.
151             if (TextUtils.isEmpty(mPhoneNumberString)) {
152                 return mId == ((PhoneCallLog) object).mId;
153             } else {
154                 return mI18nPhoneNumberWrapper.equals(
155                         ((PhoneCallLog) object).mI18nPhoneNumberWrapper);
156             }
157         }
158         return false;
159     }
160 
161     @Override
hashCode()162     public int hashCode() {
163         if (TextUtils.isEmpty(mPhoneNumberString)) {
164             return Long.hashCode(mId);
165         } else {
166             return Objects.hashCode(mI18nPhoneNumberWrapper);
167         }
168     }
169 
170     @Override
toString()171     public String toString() {
172         StringBuilder sb = new StringBuilder();
173         sb.append("PhoneNumber: ");
174         sb.append(TelecomUtils.piiLog(mPhoneNumberString));
175         sb.append(" CallLog: ");
176         sb.append(mCallRecords.size());
177         sb.append(" Account: ");
178         sb.append(mAccountName);
179         return sb.toString();
180     }
181 }
182