• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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 
18 package android.provider;
19 
20 import android.Manifest;
21 import android.annotation.CallbackExecutor;
22 import android.annotation.IntDef;
23 import android.annotation.LongDef;
24 import android.annotation.NonNull;
25 import android.annotation.RequiresPermission;
26 import android.annotation.SuppressLint;
27 import android.annotation.SystemApi;
28 import android.annotation.UserHandleAware;
29 import android.compat.annotation.UnsupportedAppUsage;
30 import android.content.ContentProvider;
31 import android.content.ContentResolver;
32 import android.content.ContentValues;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.content.pm.UserInfo;
36 import android.database.Cursor;
37 import android.location.Country;
38 import android.location.CountryDetector;
39 import android.net.Uri;
40 import android.os.Build;
41 import android.os.OutcomeReceiver;
42 import android.os.ParcelFileDescriptor;
43 import android.os.ParcelableException;
44 import android.os.UserHandle;
45 import android.os.UserManager;
46 import android.provider.ContactsContract.CommonDataKinds.Callable;
47 import android.provider.ContactsContract.CommonDataKinds.Phone;
48 import android.provider.ContactsContract.Data;
49 import android.provider.ContactsContract.DataUsageFeedback;
50 import android.telecom.CallerInfo;
51 import android.telecom.PhoneAccount;
52 import android.telecom.PhoneAccountHandle;
53 import android.telecom.TelecomManager;
54 import android.telephony.PhoneNumberUtils;
55 import android.text.TextUtils;
56 import android.util.Log;
57 
58 import java.io.ByteArrayOutputStream;
59 import java.io.FileNotFoundException;
60 import java.io.FileOutputStream;
61 import java.io.IOException;
62 import java.io.InputStream;
63 import java.lang.annotation.Retention;
64 import java.lang.annotation.RetentionPolicy;
65 import java.util.List;
66 import java.util.Objects;
67 import java.util.concurrent.Executor;
68 
69 /**
70  * The CallLog provider contains information about placed and received calls.
71  */
72 public class CallLog {
73     private static final String LOG_TAG = "CallLog";
74     private static final boolean VERBOSE_LOG = false; // DON'T SUBMIT WITH TRUE.
75 
76     public static final String AUTHORITY = "call_log";
77 
78     /**
79      * The content:// style URL for this provider
80      */
81     public static final Uri CONTENT_URI =
82         Uri.parse("content://" + AUTHORITY);
83 
84     /** @hide */
85     public static final String CALL_COMPOSER_SEGMENT = "call_composer";
86 
87     /** @hide */
88     public static final Uri CALL_COMPOSER_PICTURE_URI =
89             CONTENT_URI.buildUpon().appendPath(CALL_COMPOSER_SEGMENT).build();
90 
91     /**
92      * The "shadow" provider stores calllog when the real calllog provider is encrypted.  The
93      * real provider will alter copy from it when it starts, and remove the entries in the shadow.
94      *
95      * <p>See the comment in {@link Calls#addCall} for the details.
96      *
97      * @hide
98      */
99     public static final String SHADOW_AUTHORITY = "call_log_shadow";
100 
101     /** @hide */
102     public static final Uri SHADOW_CALL_COMPOSER_PICTURE_URI = CALL_COMPOSER_PICTURE_URI.buildUpon()
103             .authority(SHADOW_AUTHORITY).build();
104 
105     /**
106      * Describes an error encountered while storing a call composer picture in the call log.
107      * @hide
108      */
109     @SystemApi
110     public static class CallComposerLoggingException extends Throwable {
111         /**
112          * Indicates an unknown error.
113          */
114         public static final int ERROR_UNKNOWN = 0;
115 
116         /**
117          * Indicates that the process hosting the call log died or otherwise encountered an
118          * unrecoverable error while storing the picture.
119          *
120          * The caller should retry if this error is encountered.
121          */
122         public static final int ERROR_REMOTE_END_CLOSED = 1;
123 
124         /**
125          * Indicates that the device has insufficient space to store this picture.
126          *
127          * The caller should not retry if this error is encountered.
128          */
129         public static final int ERROR_STORAGE_FULL = 2;
130 
131         /**
132          * Indicates that the {@link InputStream} passed to {@link #storeCallComposerPicture}
133          * was closed.
134          *
135          * The caller should retry if this error is encountered, and be sure to not close the stream
136          * before the callback is called this time.
137          */
138         public static final int ERROR_INPUT_CLOSED = 3;
139 
140         /** @hide */
141         @IntDef(prefix = {"ERROR_"}, value = {
142                 ERROR_UNKNOWN,
143                 ERROR_REMOTE_END_CLOSED,
144                 ERROR_STORAGE_FULL,
145                 ERROR_INPUT_CLOSED,
146         })
147         @Retention(RetentionPolicy.SOURCE)
148         public @interface CallComposerLoggingError { }
149 
150         private final int mErrorCode;
151 
CallComposerLoggingException(@allComposerLoggingError int errorCode)152         public CallComposerLoggingException(@CallComposerLoggingError int errorCode) {
153             mErrorCode = errorCode;
154         }
155 
156         /**
157          * @return The error code for this exception.
158          */
getErrorCode()159         public @CallComposerLoggingError int getErrorCode() {
160             return mErrorCode;
161         }
162 
163         @Override
toString()164         public String toString() {
165             String errorString;
166             switch (mErrorCode) {
167                 case ERROR_UNKNOWN:
168                     errorString = "UNKNOWN";
169                     break;
170                 case ERROR_REMOTE_END_CLOSED:
171                     errorString = "REMOTE_END_CLOSED";
172                     break;
173                 case ERROR_STORAGE_FULL:
174                     errorString = "STORAGE_FULL";
175                     break;
176                 case ERROR_INPUT_CLOSED:
177                     errorString = "INPUT_CLOSED";
178                     break;
179                 default:
180                     errorString = "[[" + mErrorCode + "]]";
181                     break;
182             }
183             return "CallComposerLoggingException: " + errorString;
184         }
185     }
186 
187     /**
188      * Supplies a call composer picture to the call log for persistent storage.
189      *
190      * This method is used by Telephony to store pictures selected by the user or sent from the
191      * remote party as part of a voice call with call composer. The {@link Uri} supplied in the
192      * callback can be used to retrieve the image via {@link ContentResolver#openFile} or stored in
193      * the {@link Calls} table in the {@link Calls#COMPOSER_PHOTO_URI} column.
194      *
195      * The caller is responsible for closing the {@link InputStream} after the callback indicating
196      * success or failure.
197      *
198      * @param context An instance of {@link Context}. The picture will be stored to the user
199      *                corresponding to {@link Context#getUser()}.
200      * @param input An input stream from which the picture to store should be read. The input data
201      *              must be decodeable as either a JPEG, PNG, or GIF image.
202      * @param executor The {@link Executor} on which to perform the file transfer operation and
203      *                 call the supplied callback.
204      * @param callback Callback that's called after the picture is successfully stored or when an
205      *                 error occurs.
206      * @hide
207      */
208     @SystemApi
209     @UserHandleAware
210     @RequiresPermission(allOf = {
211             Manifest.permission.WRITE_CALL_LOG,
212             Manifest.permission.INTERACT_ACROSS_USERS
213     })
storeCallComposerPicture(@onNull Context context, @NonNull InputStream input, @CallbackExecutor @NonNull Executor executor, @NonNull OutcomeReceiver<Uri, CallComposerLoggingException> callback)214     public static void storeCallComposerPicture(@NonNull Context context,
215             @NonNull InputStream input,
216             @CallbackExecutor @NonNull Executor executor,
217             @NonNull OutcomeReceiver<Uri, CallComposerLoggingException> callback) {
218         Objects.requireNonNull(context);
219         Objects.requireNonNull(input);
220         Objects.requireNonNull(executor);
221         Objects.requireNonNull(callback);
222 
223         executor.execute(() -> {
224             ByteArrayOutputStream tmpOut = new ByteArrayOutputStream();
225 
226             // Read the entire input into memory first in case we have to write multiple times and
227             // the input isn't resettable.
228             byte[] buffer = new byte[1024];
229             int bytesRead;
230             while (true) {
231                 try {
232                     bytesRead = input.read(buffer);
233                 } catch (IOException e) {
234                     Log.e(LOG_TAG, "IOException while reading call composer pic from input: "
235                             + e);
236                     callback.onError(new CallComposerLoggingException(
237                             CallComposerLoggingException.ERROR_INPUT_CLOSED));
238                     return;
239                 }
240                 if (bytesRead < 0) {
241                     break;
242                 }
243                 tmpOut.write(buffer, 0, bytesRead);
244             }
245             byte[] picData = tmpOut.toByteArray();
246 
247             UserManager userManager = context.getSystemService(UserManager.class);
248             UserHandle user = context.getUser();
249             // Nasty casework for the shadow calllog begins...
250             // First see if we're just inserting for one user. If so, insert into the shadow
251             // based on whether that user is unlocked.
252             UserHandle realUser = UserHandle.CURRENT.equals(user)
253                     ? android.os.Process.myUserHandle() : user;
254             if (realUser != UserHandle.ALL) {
255                 Uri baseUri = userManager.isUserUnlocked(realUser) ? CALL_COMPOSER_PICTURE_URI
256                         : SHADOW_CALL_COMPOSER_PICTURE_URI;
257                 Uri pictureInsertionUri = ContentProvider.maybeAddUserId(baseUri,
258                         realUser.getIdentifier());
259                 Log.i(LOG_TAG, "Inserting call composer for single user at "
260                         + pictureInsertionUri);
261 
262                 try {
263                     Uri result = storeCallComposerPictureAtUri(
264                             context, pictureInsertionUri, false, picData);
265                     callback.onResult(result);
266                 } catch (CallComposerLoggingException e) {
267                     callback.onError(e);
268                 }
269                 return;
270             }
271 
272             // Next, see if the system user is locked. If so, only insert to the system shadow
273             if (!userManager.isUserUnlocked(UserHandle.SYSTEM)) {
274                 Uri pictureInsertionUri = ContentProvider.maybeAddUserId(
275                         SHADOW_CALL_COMPOSER_PICTURE_URI,
276                         UserHandle.SYSTEM.getIdentifier());
277                 Log.i(LOG_TAG, "Inserting call composer for all users, but system locked at "
278                         + pictureInsertionUri);
279                 try {
280                     Uri result =
281                             storeCallComposerPictureAtUri(context, pictureInsertionUri,
282                                     true, picData);
283                     callback.onResult(result);
284                 } catch (CallComposerLoggingException e) {
285                     callback.onError(e);
286                 }
287                 return;
288             }
289 
290             // If we're inserting to all users and the system user is unlocked, then insert to all
291             // running users. Non running/still locked users will copy from the system when they
292             // start.
293             // First, insert to the system calllog to get the basename to use for the rest of the
294             // users.
295             Uri systemPictureInsertionUri = ContentProvider.maybeAddUserId(
296                     CALL_COMPOSER_PICTURE_URI,
297                     UserHandle.SYSTEM.getIdentifier());
298             Uri systemInsertedPicture;
299             try {
300                 systemInsertedPicture =
301                         storeCallComposerPictureAtUri(context, systemPictureInsertionUri,
302                                 true, picData);
303                 Log.i(LOG_TAG, "Inserting call composer for all users, succeeded with system,"
304                         + " result is " + systemInsertedPicture);
305             } catch (CallComposerLoggingException e) {
306                 callback.onError(e);
307                 return;
308             }
309 
310             // Next, insert into all users that have call log access AND are running AND are
311             // decrypted.
312             Uri strippedInsertionUri = ContentProvider.getUriWithoutUserId(systemInsertedPicture);
313             for (UserInfo u : userManager.getAliveUsers()) {
314                 UserHandle userHandle = u.getUserHandle();
315                 if (userHandle.isSystem()) {
316                     // Already written.
317                     continue;
318                 }
319 
320                 if (!Calls.shouldHaveSharedCallLogEntries(
321                         context, userManager, userHandle.getIdentifier())) {
322                     // Shouldn't have calllog entries.
323                     continue;
324                 }
325 
326                 if (userManager.isUserRunning(userHandle)
327                         && userManager.isUserUnlocked(userHandle)) {
328                     Uri insertionUri = ContentProvider.maybeAddUserId(strippedInsertionUri,
329                             userHandle.getIdentifier());
330                     Log.i(LOG_TAG, "Inserting call composer for all users, now on user "
331                             + userHandle + " inserting at " + insertionUri);
332                     try {
333                         storeCallComposerPictureAtUri(context, insertionUri, false, picData);
334                     } catch (CallComposerLoggingException e) {
335                         Log.e(LOG_TAG, "Error writing for user " + userHandle.getIdentifier()
336                                 + ": " + e);
337                         // If one or more users failed but the system user succeeded, don't return
338                         // an error -- the image is still around somewhere, and we'll be able to
339                         // find it in the system user's call log if needed.
340                     }
341                 }
342             }
343             callback.onResult(strippedInsertionUri);
344         });
345     }
346 
storeCallComposerPictureAtUri( Context context, Uri insertionUri, boolean forAllUsers, byte[] picData)347     private static Uri storeCallComposerPictureAtUri(
348             Context context, Uri insertionUri,
349             boolean forAllUsers, byte[] picData) throws CallComposerLoggingException {
350         Uri pictureFileUri;
351         try {
352             ContentValues cv = new ContentValues();
353             cv.put(Calls.ADD_FOR_ALL_USERS, forAllUsers ? 1 : 0);
354             pictureFileUri = context.getContentResolver().insert(insertionUri, cv);
355         } catch (ParcelableException e) {
356             // Most likely an IOException. We don't have a good way of distinguishing them so
357             // just return an unknown error.
358             throw new CallComposerLoggingException(CallComposerLoggingException.ERROR_UNKNOWN);
359         }
360         if (pictureFileUri == null) {
361             // If the call log provider returns null, it means that there's not enough space
362             // left to store the maximum-sized call composer image.
363             throw new CallComposerLoggingException(CallComposerLoggingException.ERROR_STORAGE_FULL);
364         }
365 
366         try (ParcelFileDescriptor pfd =
367                      context.getContentResolver().openFileDescriptor(pictureFileUri, "w")) {
368             FileOutputStream output = new FileOutputStream(pfd.getFileDescriptor());
369             try {
370                 output.write(picData);
371             } catch (IOException e) {
372                 Log.e(LOG_TAG, "Got IOException writing to remote end: " + e);
373                 // Clean up our mess if we didn't successfully write the file.
374                 context.getContentResolver().delete(pictureFileUri, null);
375                 throw new CallComposerLoggingException(
376                         CallComposerLoggingException.ERROR_REMOTE_END_CLOSED);
377             }
378         } catch (FileNotFoundException e) {
379             throw new CallComposerLoggingException(CallComposerLoggingException.ERROR_UNKNOWN);
380         } catch (IOException e) {
381             // Ignore, this is only thrown upon closing.
382             Log.e(LOG_TAG, "Got IOException closing remote descriptor: " + e);
383         }
384         return pictureFileUri;
385     }
386 
387     // Only call on the correct executor.
sendCallComposerError(OutcomeReceiver<?, CallComposerLoggingException> cb, int error)388     private static void sendCallComposerError(OutcomeReceiver<?, CallComposerLoggingException> cb,
389             int error) {
390         cb.onError(new CallComposerLoggingException(error));
391     }
392 
393     /**
394      * Used as an argument to {@link Calls#addCall(Context, AddCallParams)}.
395      *
396      * Contains details to log about a call.
397      * @hide
398      */
399     public static class AddCallParams {
400 
401         /**
402          * Builder for the add-call parameters.
403          */
404         public static final class AddCallParametersBuilder {
405             private CallerInfo mCallerInfo;
406             private String mNumber;
407             private String mPostDialDigits;
408             private String mViaNumber;
409             private int mPresentation = TelecomManager.PRESENTATION_UNKNOWN;
410             private int mCallType = Calls.INCOMING_TYPE;
411             private int mFeatures;
412             private PhoneAccountHandle mAccountHandle;
413             private long mStart;
414             private int mDuration;
415             private Long mDataUsage = Long.MIN_VALUE;
416             private boolean mAddForAllUsers;
417             private UserHandle mUserToBeInsertedTo;
418             private boolean mIsRead;
419             private int mCallBlockReason = Calls.BLOCK_REASON_NOT_BLOCKED;
420             private CharSequence mCallScreeningAppName;
421             private String mCallScreeningComponentName;
422             private long mMissedReason = Calls.MISSED_REASON_NOT_MISSED;
423             private int mPriority = Calls.PRIORITY_NORMAL;
424             private String mSubject;
425             private double mLatitude = Double.NaN;
426             private double mLongitude = Double.NaN;
427             private Uri mPictureUri;
428             private int mIsPhoneAccountMigrationPending;
429 
430             /**
431              * @param callerInfo the CallerInfo object to get the target contact from.
432              */
setCallerInfo( @onNull CallerInfo callerInfo)433             public @NonNull AddCallParametersBuilder setCallerInfo(
434                     @NonNull CallerInfo callerInfo) {
435                 mCallerInfo = callerInfo;
436                 return this;
437             }
438 
439             /**
440              * @param number the phone number to be added to the calls db
441              */
setNumber(@onNull String number)442             public @NonNull AddCallParametersBuilder setNumber(@NonNull String number) {
443                 mNumber = number;
444                 return this;
445             }
446 
447             /**
448              * @param postDialDigits the post-dial digits that were dialed after the number,
449              *        if it was outgoing. Otherwise it is ''.
450              */
setPostDialDigits( @onNull String postDialDigits)451             public @NonNull AddCallParametersBuilder setPostDialDigits(
452                     @NonNull String postDialDigits) {
453                 mPostDialDigits = postDialDigits;
454                 return this;
455             }
456 
457             /**
458              * @param viaNumber the secondary number that the incoming call received with. If the
459              *        call was received with the SIM assigned number, then this field must be ''.
460              */
setViaNumber(@onNull String viaNumber)461             public @NonNull AddCallParametersBuilder setViaNumber(@NonNull String viaNumber) {
462                 mViaNumber = viaNumber;
463                 return this;
464             }
465 
466             /**
467              * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which
468              *        is set by the network and denotes the number presenting rules for
469              *        "allowed", "payphone", "restricted" or "unknown"
470              */
setPresentation(int presentation)471             public @NonNull AddCallParametersBuilder setPresentation(int presentation) {
472                 mPresentation = presentation;
473                 return this;
474             }
475 
476             /**
477              * @param callType enumerated values for "incoming", "outgoing", or "missed"
478              */
setCallType(int callType)479             public @NonNull AddCallParametersBuilder setCallType(int callType) {
480                 mCallType = callType;
481                 return this;
482             }
483 
484             /**
485              * @param features features of the call (e.g. Video).
486              */
setFeatures(int features)487             public @NonNull AddCallParametersBuilder setFeatures(int features) {
488                 mFeatures = features;
489                 return this;
490             }
491 
492             /**
493              * @param accountHandle The accountHandle object identifying the provider of the call
494              */
setAccountHandle( @onNull PhoneAccountHandle accountHandle)495             public @NonNull AddCallParametersBuilder setAccountHandle(
496                     @NonNull PhoneAccountHandle accountHandle) {
497                 mAccountHandle = accountHandle;
498                 return this;
499             }
500 
501             /**
502              * @param start time stamp for the call in milliseconds
503              */
setStart(long start)504             public @NonNull AddCallParametersBuilder setStart(long start) {
505                 mStart = start;
506                 return this;
507             }
508 
509             /**
510              * @param duration call duration in seconds
511              */
setDuration(int duration)512             public @NonNull AddCallParametersBuilder setDuration(int duration) {
513                 mDuration = duration;
514                 return this;
515             }
516 
517             /**
518              * @param dataUsage data usage for the call in bytes or
519              *                  {@link Long#MIN_VALUE} if data usage was not tracked
520              *                  for the call.
521              */
setDataUsage(long dataUsage)522             public @NonNull AddCallParametersBuilder setDataUsage(long dataUsage) {
523                 mDataUsage = dataUsage;
524                 return this;
525             }
526 
527             /**
528              * @param addForAllUsers If true, the call is added to the call log of all currently
529              *        running users. The caller must have the MANAGE_USERS permission if this is
530              *        true.
531              */
setAddForAllUsers( boolean addForAllUsers)532             public @NonNull AddCallParametersBuilder setAddForAllUsers(
533                     boolean addForAllUsers) {
534                 mAddForAllUsers = addForAllUsers;
535                 return this;
536             }
537 
538             /**
539              * @param userToBeInsertedTo {@link UserHandle} of user that the call is going to be
540              *                           inserted to. null if it is inserted to the current user.
541              *                           The value is ignored if {@link #setAddForAllUsers} is
542              *                           called with {@code true}.
543              */
544             @SuppressLint("UserHandleName")
setUserToBeInsertedTo( @onNull UserHandle userToBeInsertedTo)545             public @NonNull AddCallParametersBuilder setUserToBeInsertedTo(
546                     @NonNull UserHandle userToBeInsertedTo) {
547                 mUserToBeInsertedTo = userToBeInsertedTo;
548                 return this;
549             }
550 
551             /**
552              * @param isRead Flag to show if the missed call log has been read by the user or not.
553              *                Used for call log restore of missed calls.
554              */
setIsRead(boolean isRead)555             public @NonNull AddCallParametersBuilder setIsRead(boolean isRead) {
556                 mIsRead = isRead;
557                 return this;
558             }
559 
560             /**
561              * @param callBlockReason The reason why the call is blocked.
562              */
setCallBlockReason(int callBlockReason)563             public @NonNull AddCallParametersBuilder setCallBlockReason(int callBlockReason) {
564                 mCallBlockReason = callBlockReason;
565                 return this;
566             }
567 
568             /**
569              * @param callScreeningAppName The call screening application name which block the call.
570              */
setCallScreeningAppName( @onNull CharSequence callScreeningAppName)571             public @NonNull AddCallParametersBuilder setCallScreeningAppName(
572                     @NonNull CharSequence callScreeningAppName) {
573                 mCallScreeningAppName = callScreeningAppName;
574                 return this;
575             }
576 
577             /**
578              * @param callScreeningComponentName The call screening component name which blocked
579              *                                   the call.
580              */
setCallScreeningComponentName( @onNull String callScreeningComponentName)581             public @NonNull AddCallParametersBuilder setCallScreeningComponentName(
582                     @NonNull String callScreeningComponentName) {
583                 mCallScreeningComponentName = callScreeningComponentName;
584                 return this;
585             }
586 
587             /**
588              * @param missedReason The encoded missed information of the call.
589              */
setMissedReason(long missedReason)590             public @NonNull AddCallParametersBuilder setMissedReason(long missedReason) {
591                 mMissedReason = missedReason;
592                 return this;
593             }
594 
595             /**
596              * @param priority The priority of the call, either {@link Calls#PRIORITY_NORMAL}
597              *                 or {@link Calls#PRIORITY_URGENT} as sent via call composer
598              */
setPriority(int priority)599             public @NonNull AddCallParametersBuilder setPriority(int priority) {
600                 mPriority = priority;
601                 return this;
602             }
603 
604             /**
605              * @param subject The subject as sent via call composer.
606              */
setSubject(@onNull String subject)607             public @NonNull AddCallParametersBuilder setSubject(@NonNull String subject) {
608                 mSubject = subject;
609                 return this;
610             }
611 
612             /**
613              * @param latitude Latitude of the location sent via call composer.
614              */
setLatitude(double latitude)615             public @NonNull AddCallParametersBuilder setLatitude(double latitude) {
616                 mLatitude = latitude;
617                 return this;
618             }
619 
620             /**
621              * @param longitude Longitude of the location sent via call composer.
622              */
setLongitude(double longitude)623             public @NonNull AddCallParametersBuilder setLongitude(double longitude) {
624                 mLongitude = longitude;
625                 return this;
626             }
627 
628             /**
629              * @param pictureUri {@link Uri} returned from {@link #storeCallComposerPicture}.
630              *                   Associates that stored picture with this call in the log.
631              */
setPictureUri(@onNull Uri pictureUri)632             public @NonNull AddCallParametersBuilder setPictureUri(@NonNull Uri pictureUri) {
633                 mPictureUri = pictureUri;
634                 return this;
635             }
636 
637             /**
638              * @param isPhoneAccountMigrationPending whether the phone account migration is pending
639              */
setIsPhoneAccountMigrationPending( int isPhoneAccountMigrationPending)640             public @NonNull AddCallParametersBuilder setIsPhoneAccountMigrationPending(
641                     int isPhoneAccountMigrationPending) {
642                 mIsPhoneAccountMigrationPending = isPhoneAccountMigrationPending;
643                 return this;
644             }
645 
646             /**
647              * Builds the object
648              */
build()649             public @NonNull AddCallParams build() {
650                 return new AddCallParams(mCallerInfo, mNumber, mPostDialDigits, mViaNumber,
651                         mPresentation, mCallType, mFeatures, mAccountHandle, mStart, mDuration,
652                         mDataUsage, mAddForAllUsers, mUserToBeInsertedTo, mIsRead, mCallBlockReason,
653                         mCallScreeningAppName, mCallScreeningComponentName, mMissedReason,
654                         mPriority, mSubject, mLatitude, mLongitude, mPictureUri,
655                         mIsPhoneAccountMigrationPending);
656             }
657         }
658 
659         private CallerInfo mCallerInfo;
660         private String mNumber;
661         private String mPostDialDigits;
662         private String mViaNumber;
663         private int mPresentation;
664         private int mCallType;
665         private int mFeatures;
666         private PhoneAccountHandle mAccountHandle;
667         private long mStart;
668         private int mDuration;
669         private long mDataUsage;
670         private boolean mAddForAllUsers;
671         private UserHandle mUserToBeInsertedTo;
672         private boolean mIsRead;
673         private int mCallBlockReason;
674         private CharSequence mCallScreeningAppName;
675         private String mCallScreeningComponentName;
676         private long mMissedReason;
677         private int mPriority;
678         private String mSubject;
679         private double mLatitude = Double.NaN;
680         private double mLongitude = Double.NaN;
681         private Uri mPictureUri;
682         private int mIsPhoneAccountMigrationPending;
683 
AddCallParams(CallerInfo callerInfo, String number, String postDialDigits, String viaNumber, int presentation, int callType, int features, PhoneAccountHandle accountHandle, long start, int duration, long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo, boolean isRead, int callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName, long missedReason, int priority, String subject, double latitude, double longitude, Uri pictureUri, int isPhoneAccountMigrationPending)684         private AddCallParams(CallerInfo callerInfo, String number, String postDialDigits,
685                 String viaNumber, int presentation, int callType, int features,
686                 PhoneAccountHandle accountHandle, long start, int duration, long dataUsage,
687                 boolean addForAllUsers, UserHandle userToBeInsertedTo, boolean isRead,
688                 int callBlockReason,
689                 CharSequence callScreeningAppName, String callScreeningComponentName,
690                 long missedReason,
691                 int priority, String subject, double latitude, double longitude, Uri pictureUri,
692                 int isPhoneAccountMigrationPending) {
693             mCallerInfo = callerInfo;
694             mNumber = number;
695             mPostDialDigits = postDialDigits;
696             mViaNumber = viaNumber;
697             mPresentation = presentation;
698             mCallType = callType;
699             mFeatures = features;
700             mAccountHandle = accountHandle;
701             mStart = start;
702             mDuration = duration;
703             mDataUsage = dataUsage;
704             mAddForAllUsers = addForAllUsers;
705             mUserToBeInsertedTo = userToBeInsertedTo;
706             mIsRead = isRead;
707             mCallBlockReason = callBlockReason;
708             mCallScreeningAppName = callScreeningAppName;
709             mCallScreeningComponentName = callScreeningComponentName;
710             mMissedReason = missedReason;
711             mPriority = priority;
712             mSubject = subject;
713             mLatitude = latitude;
714             mLongitude = longitude;
715             mPictureUri = pictureUri;
716             mIsPhoneAccountMigrationPending = isPhoneAccountMigrationPending;
717         }
718 
719     }
720 
721     /**
722      * Contains the recent calls.
723      * <p>
724      * Note: If you want to query the call log and limit the results to a single value, you should
725      * append the {@link #LIMIT_PARAM_KEY} parameter to the content URI.  For example:
726      * <pre>
727      * {@code
728      * getContentResolver().query(
729      *                 Calls.CONTENT_URI.buildUpon().appendQueryParameter(LIMIT_PARAM_KEY, "1")
730      *                 .build(),
731      *                 null, null, null, null);
732      * }
733      * </pre>
734      * <p>
735      * The call log provider enforces strict SQL grammar, so you CANNOT append "LIMIT" to the SQL
736      * query as below:
737      * <pre>
738      * {@code
739      * getContentResolver().query(Calls.CONTENT_URI, null, "LIMIT 1", null, null);
740      * }
741      * </pre>
742      */
743     public static class Calls implements BaseColumns {
744         /**
745          * The content:// style URL for this table
746          */
747         public static final Uri CONTENT_URI =
748                 Uri.parse("content://call_log/calls");
749 
750         /** @hide */
751         public static final Uri SHADOW_CONTENT_URI =
752                 Uri.parse("content://call_log_shadow/calls");
753 
754         /**
755          * The content:// style URL for filtering this table on phone numbers
756          */
757         public static final Uri CONTENT_FILTER_URI =
758                 Uri.parse("content://call_log/calls/filter");
759 
760         /**
761          * Query parameter used to limit the number of call logs returned.
762          * <p>
763          * TYPE: integer
764          */
765         public static final String LIMIT_PARAM_KEY = "limit";
766 
767         /**
768          * Form of {@link #CONTENT_URI} which limits the query results to a single result.
769          */
770         private static final Uri CONTENT_URI_LIMIT_1 = CONTENT_URI.buildUpon()
771                 .appendQueryParameter(LIMIT_PARAM_KEY, "1")
772                 .build();
773 
774         /**
775          * Query parameter used to specify the starting record to return.
776          * <p>
777          * TYPE: integer
778          */
779         public static final String OFFSET_PARAM_KEY = "offset";
780 
781         /**
782          * An optional URI parameter which instructs the provider to allow the operation to be
783          * applied to voicemail records as well.
784          * <p>
785          * TYPE: Boolean
786          * <p>
787          * Using this parameter with a value of {@code true} will result in a security error if the
788          * calling package does not have appropriate permissions to access voicemails.
789          *
790          * @hide
791          */
792         public static final String ALLOW_VOICEMAILS_PARAM_KEY = "allow_voicemails";
793 
794         /**
795          * An optional extra used with {@link #CONTENT_TYPE Calls.CONTENT_TYPE} and
796          * {@link Intent#ACTION_VIEW} to specify that the presented list of calls should be
797          * filtered for a particular call type.
798          *
799          * Applications implementing a call log UI should check for this extra, and display a
800          * filtered list of calls based on the specified call type. If not applicable within the
801          * application's UI, it should be silently ignored.
802          *
803          * <p>
804          * The following example brings up the call log, showing only missed calls.
805          * <pre>
806          * Intent intent = new Intent(Intent.ACTION_VIEW);
807          * intent.setType(CallLog.Calls.CONTENT_TYPE);
808          * intent.putExtra(CallLog.Calls.EXTRA_CALL_TYPE_FILTER, CallLog.Calls.MISSED_TYPE);
809          * startActivity(intent);
810          * </pre>
811          * </p>
812          */
813         public static final String EXTRA_CALL_TYPE_FILTER =
814                 "android.provider.extra.CALL_TYPE_FILTER";
815 
816         /**
817          * Content uri used to access call log entries, including voicemail records. You must have
818          * the READ_CALL_LOG and WRITE_CALL_LOG permissions to read and write to the call log, as
819          * well as READ_VOICEMAIL and WRITE_VOICEMAIL permissions to read and write voicemails.
820          */
821         public static final Uri CONTENT_URI_WITH_VOICEMAIL = CONTENT_URI.buildUpon()
822                 .appendQueryParameter(ALLOW_VOICEMAILS_PARAM_KEY, "true")
823                 .build();
824 
825         /**
826          * The default sort order for this table
827          */
828         public static final String DEFAULT_SORT_ORDER = "date DESC";
829 
830         /**
831          * The MIME type of {@link #CONTENT_URI} and {@link #CONTENT_FILTER_URI}
832          * providing a directory of calls.
833          */
834         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/calls";
835 
836         /**
837          * The MIME type of a {@link #CONTENT_URI} sub-directory of a single
838          * call.
839          */
840         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls";
841 
842         /**
843          * The type of the call (incoming, outgoing or missed).
844          * <P>Type: INTEGER (int)</P>
845          *
846          * <p>
847          * Allowed values:
848          * <ul>
849          * <li>{@link #INCOMING_TYPE}</li>
850          * <li>{@link #OUTGOING_TYPE}</li>
851          * <li>{@link #MISSED_TYPE}</li>
852          * <li>{@link #VOICEMAIL_TYPE}</li>
853          * <li>{@link #REJECTED_TYPE}</li>
854          * <li>{@link #BLOCKED_TYPE}</li>
855          * <li>{@link #ANSWERED_EXTERNALLY_TYPE}</li>
856          * </ul>
857          * </p>
858          */
859         public static final String TYPE = "type";
860 
861         /** Call log type for incoming calls. */
862         public static final int INCOMING_TYPE = 1;
863         /** Call log type for outgoing calls. */
864         public static final int OUTGOING_TYPE = 2;
865         /** Call log type for missed calls. */
866         public static final int MISSED_TYPE = 3;
867         /** Call log type for voicemails. */
868         public static final int VOICEMAIL_TYPE = 4;
869         /** Call log type for calls rejected by direct user action. */
870         public static final int REJECTED_TYPE = 5;
871         /** Call log type for calls blocked automatically. */
872         public static final int BLOCKED_TYPE = 6;
873         /**
874          * Call log type for a call which was answered on another device.  Used in situations where
875          * a call rings on multiple devices simultaneously and it ended up being answered on a
876          * device other than the current one.
877          */
878         public static final int ANSWERED_EXTERNALLY_TYPE = 7;
879 
880         /**
881          * Bit-mask describing features of the call (e.g. video).
882          *
883          * <P>Type: INTEGER (int)</P>
884          */
885         public static final String FEATURES = "features";
886 
887         /** Call had video. */
888         public static final int FEATURES_VIDEO = 1 << 0;
889 
890         /** Call was pulled externally. */
891         public static final int FEATURES_PULLED_EXTERNALLY = 1 << 1;
892 
893         /** Call was HD. */
894         public static final int FEATURES_HD_CALL = 1 << 2;
895 
896         /** Call was WIFI call. */
897         public static final int FEATURES_WIFI = 1 << 3;
898 
899         /**
900          * Indicates the call underwent Assisted Dialing.
901          * @see TelecomManager#EXTRA_USE_ASSISTED_DIALING
902          */
903         public static final int FEATURES_ASSISTED_DIALING_USED = 1 << 4;
904 
905         /** Call was on RTT at some point */
906         public static final int FEATURES_RTT = 1 << 5;
907 
908         /** Call was VoLTE */
909         public static final int FEATURES_VOLTE = 1 << 6;
910 
911         /**
912          * The phone number as the user entered it.
913          * <P>Type: TEXT</P>
914          */
915         public static final String NUMBER = "number";
916 
917         /**
918          * The number presenting rules set by the network.
919          *
920          * <p>
921          * Allowed values:
922          * <ul>
923          * <li>{@link #PRESENTATION_ALLOWED}</li>
924          * <li>{@link #PRESENTATION_RESTRICTED}</li>
925          * <li>{@link #PRESENTATION_UNKNOWN}</li>
926          * <li>{@link #PRESENTATION_PAYPHONE}</li>
927          * <li>{@link #PRESENTATION_UNAVAILABLE}</li>
928          * </ul>
929          * </p>
930          *
931          * <P>Type: INTEGER</P>
932          */
933         public static final String NUMBER_PRESENTATION = "presentation";
934 
935         /** Number is allowed to display for caller id. */
936         public static final int PRESENTATION_ALLOWED = 1;
937         /** Number is blocked by user. */
938         public static final int PRESENTATION_RESTRICTED = 2;
939         /** Number is not specified or unknown by network. */
940         public static final int PRESENTATION_UNKNOWN = 3;
941         /** Number is a pay phone. */
942         public static final int PRESENTATION_PAYPHONE = 4;
943         /** Number is unavailable. */
944         public static final int PRESENTATION_UNAVAILABLE = 5;
945 
946         /**
947          * The ISO 3166-1 two letters country code of the country where the
948          * user received or made the call.
949          * <P>
950          * Type: TEXT
951          * </P>
952          */
953         public static final String COUNTRY_ISO = "countryiso";
954 
955         /**
956          * The date the call occured, in milliseconds since the epoch
957          * <P>Type: INTEGER (long)</P>
958          */
959         public static final String DATE = "date";
960 
961         /**
962          * The duration of the call in seconds
963          * <P>Type: INTEGER (long)</P>
964          */
965         public static final String DURATION = "duration";
966 
967         /**
968          * The data usage of the call in bytes.
969          * <P>Type: INTEGER (long)</P>
970          */
971         public static final String DATA_USAGE = "data_usage";
972 
973         /**
974          * Whether or not the call has been acknowledged
975          * <P>Type: INTEGER (boolean)</P>
976          */
977         public static final String NEW = "new";
978 
979         /**
980          * The cached name associated with the phone number, if it exists.
981          *
982          * <p>This value is typically filled in by the dialer app for the caching purpose,
983          * so it's not guaranteed to be present, and may not be current if the contact
984          * information associated with this number has changed.
985          * <P>Type: TEXT</P>
986          */
987         public static final String CACHED_NAME = "name";
988 
989         /**
990          * The cached number type (Home, Work, etc) associated with the
991          * phone number, if it exists.
992          *
993          * <p>This value is typically filled in by the dialer app for the caching purpose,
994          * so it's not guaranteed to be present, and may not be current if the contact
995          * information associated with this number has changed.
996          * <P>Type: INTEGER</P>
997          */
998         public static final String CACHED_NUMBER_TYPE = "numbertype";
999 
1000         /**
1001          * The cached number label, for a custom number type, associated with the
1002          * phone number, if it exists.
1003          *
1004          * <p>This value is typically filled in by the dialer app for the caching purpose,
1005          * so it's not guaranteed to be present, and may not be current if the contact
1006          * information associated with this number has changed.
1007          * <P>Type: TEXT</P>
1008          */
1009         public static final String CACHED_NUMBER_LABEL = "numberlabel";
1010 
1011         /**
1012          * URI of the voicemail entry. Populated only for {@link #VOICEMAIL_TYPE}.
1013          * <P>Type: TEXT</P>
1014          */
1015         public static final String VOICEMAIL_URI = "voicemail_uri";
1016 
1017         /**
1018          * Transcription of the call or voicemail entry. This will only be populated for call log
1019          * entries of type {@link #VOICEMAIL_TYPE} that have valid transcriptions.
1020          */
1021         public static final String TRANSCRIPTION = "transcription";
1022 
1023         /**
1024          * State of voicemail transcription entry. This will only be populated for call log
1025          * entries of type {@link #VOICEMAIL_TYPE}.
1026          * @hide
1027          */
1028         public static final String TRANSCRIPTION_STATE = "transcription_state";
1029 
1030         /**
1031          * Whether this item has been read or otherwise consumed by the user.
1032          * <p>
1033          * Unlike the {@link #NEW} field, which requires the user to have acknowledged the
1034          * existence of the entry, this implies the user has interacted with the entry.
1035          * <P>Type: INTEGER (boolean)</P>
1036          */
1037         public static final String IS_READ = "is_read";
1038 
1039         /**
1040          * A geocoded location for the number associated with this call.
1041          * <p>
1042          * The string represents a city, state, or country associated with the number.
1043          * <P>Type: TEXT</P>
1044          */
1045         public static final String GEOCODED_LOCATION = "geocoded_location";
1046 
1047         /**
1048          * The cached URI to look up the contact associated with the phone number, if it exists.
1049          *
1050          * <p>This value is typically filled in by the dialer app for the caching purpose,
1051          * so it's not guaranteed to be present, and may not be current if the contact
1052          * information associated with this number has changed.
1053          * <P>Type: TEXT</P>
1054          */
1055         public static final String CACHED_LOOKUP_URI = "lookup_uri";
1056 
1057         /**
1058          * The cached phone number of the contact which matches this entry, if it exists.
1059          *
1060          * <p>This value is typically filled in by the dialer app for the caching purpose,
1061          * so it's not guaranteed to be present, and may not be current if the contact
1062          * information associated with this number has changed.
1063          * <P>Type: TEXT</P>
1064          */
1065         public static final String CACHED_MATCHED_NUMBER = "matched_number";
1066 
1067         /**
1068          * The cached normalized(E164) version of the phone number, if it exists.
1069          *
1070          * <p>This value is typically filled in by the dialer app for the caching purpose,
1071          * so it's not guaranteed to be present, and may not be current if the contact
1072          * information associated with this number has changed.
1073          * <P>Type: TEXT</P>
1074          */
1075         public static final String CACHED_NORMALIZED_NUMBER = "normalized_number";
1076 
1077         /**
1078          * The cached photo id of the picture associated with the phone number, if it exists.
1079          *
1080          * <p>This value is typically filled in by the dialer app for the caching purpose,
1081          * so it's not guaranteed to be present, and may not be current if the contact
1082          * information associated with this number has changed.
1083          * <P>Type: INTEGER (long)</P>
1084          */
1085         public static final String CACHED_PHOTO_ID = "photo_id";
1086 
1087         /**
1088          * The cached photo URI of the picture associated with the phone number, if it exists.
1089          *
1090          * <p>This value is typically filled in by the dialer app for the caching purpose,
1091          * so it's not guaranteed to be present, and may not be current if the contact
1092          * information associated with this number has changed.
1093          * <P>Type: TEXT (URI)</P>
1094          */
1095         public static final String CACHED_PHOTO_URI = "photo_uri";
1096 
1097         /**
1098          * The cached phone number, formatted with formatting rules based on the country the
1099          * user was in when the call was made or received.
1100          *
1101          * <p>This value is typically filled in by the dialer app for the caching purpose,
1102          * so it's not guaranteed to be present, and may not be current if the contact
1103          * information associated with this number has changed.
1104          * <P>Type: TEXT</P>
1105          */
1106         public static final String CACHED_FORMATTED_NUMBER = "formatted_number";
1107 
1108         // Note: PHONE_ACCOUNT_* constant values are "subscription_*" due to a historic naming
1109         // that was encoded into call log databases.
1110 
1111         /**
1112          * The component name of the account used to place or receive the call; in string form.
1113          * <P>Type: TEXT</P>
1114          */
1115         public static final String PHONE_ACCOUNT_COMPONENT_NAME = "subscription_component_name";
1116 
1117         /**
1118          * The identifier for the account used to place or receive the call.
1119          * <P>Type: TEXT</P>
1120          */
1121         public static final String PHONE_ACCOUNT_ID = "subscription_id";
1122 
1123         /**
1124          * The address associated with the account used to place or receive the call; in string
1125          * form. For SIM-based calls, this is the user's own phone number.
1126          * <P>Type: TEXT</P>
1127          *
1128          * @hide
1129          */
1130         public static final String PHONE_ACCOUNT_ADDRESS = "phone_account_address";
1131 
1132         /**
1133          * Indicates that the entry will be hidden from all queries until the associated
1134          * {@link android.telecom.PhoneAccount} is registered with the system.
1135          * <P>Type: INTEGER</P>
1136          *
1137          * @hide
1138          */
1139         public static final String PHONE_ACCOUNT_HIDDEN = "phone_account_hidden";
1140 
1141         /**
1142          * The subscription ID used to place this call.  This is no longer used and has been
1143          * replaced with PHONE_ACCOUNT_COMPONENT_NAME/PHONE_ACCOUNT_ID.
1144          * For ContactsProvider internal use only.
1145          * <P>Type: INTEGER</P>
1146          *
1147          * @Deprecated
1148          * @hide
1149          */
1150         public static final String SUB_ID = "sub_id";
1151 
1152         /**
1153          * The post-dial portion of a dialed number, including any digits dialed after a
1154          * {@link TelecomManager#DTMF_CHARACTER_PAUSE} or a {@link
1155          * TelecomManager#DTMF_CHARACTER_WAIT} and these characters themselves.
1156          * <P>Type: TEXT</P>
1157          */
1158         public static final String POST_DIAL_DIGITS = "post_dial_digits";
1159 
1160         /**
1161          * For an incoming call, the secondary line number the call was received via.
1162          * When a SIM card has multiple phone numbers associated with it, the via number indicates
1163          * which of the numbers associated with the SIM was called.
1164          */
1165         public static final String VIA_NUMBER = "via_number";
1166 
1167         /**
1168          * Indicates that the entry will be copied from primary user to other users.
1169          * <P>Type: INTEGER</P>
1170          *
1171          * @hide
1172          */
1173         public static final String ADD_FOR_ALL_USERS = "add_for_all_users";
1174 
1175         /**
1176          * The date the row is last inserted, updated, or marked as deleted, in milliseconds
1177          * since the epoch. Read only.
1178          * <P>Type: INTEGER (long)</P>
1179          */
1180         public static final String LAST_MODIFIED = "last_modified";
1181 
1182         /**
1183          * If a successful call is made that is longer than this duration, update the phone number
1184          * in the ContactsProvider with the normalized version of the number, based on the user's
1185          * current country code.
1186          */
1187         private static final int MIN_DURATION_FOR_NORMALIZED_NUMBER_UPDATE_MS = 1000 * 10;
1188 
1189         /**
1190          * Value for {@link CallLog.Calls#BLOCK_REASON}, set as the default value when a call was
1191          * not blocked by a CallScreeningService or any other system call blocking method.
1192          */
1193         public static final int BLOCK_REASON_NOT_BLOCKED = 0;
1194 
1195         /**
1196          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
1197          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked by a
1198          * CallScreeningService. The {@link CallLog.Calls#CALL_SCREENING_COMPONENT_NAME} and
1199          * {@link CallLog.Calls#CALL_SCREENING_APP_NAME} columns will indicate which call screening
1200          * service was responsible for blocking the call.
1201          */
1202         public static final int BLOCK_REASON_CALL_SCREENING_SERVICE = 1;
1203 
1204         /**
1205          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
1206          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
1207          * configured a contact to be sent directly to voicemail.
1208          */
1209         public static final int BLOCK_REASON_DIRECT_TO_VOICEMAIL = 2;
1210 
1211         /**
1212          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
1213          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because it is
1214          * in the BlockedNumbers provider.
1215          */
1216         public static final int BLOCK_REASON_BLOCKED_NUMBER = 3;
1217 
1218         /**
1219          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
1220          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
1221          * has chosen to block all calls from unknown numbers.
1222          */
1223         public static final int BLOCK_REASON_UNKNOWN_NUMBER = 4;
1224 
1225         /**
1226          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
1227          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
1228          * has chosen to block all calls from restricted numbers.
1229          */
1230         public static final int BLOCK_REASON_RESTRICTED_NUMBER = 5;
1231 
1232         /**
1233          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
1234          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
1235          * has chosen to block all calls from pay phones.
1236          */
1237         public static final int BLOCK_REASON_PAY_PHONE = 6;
1238 
1239         /**
1240          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
1241          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
1242          * has chosen to block all calls from numbers not in their contacts.
1243          */
1244         public static final int BLOCK_REASON_NOT_IN_CONTACTS = 7;
1245 
1246         /**
1247          * The ComponentName of the CallScreeningService which blocked this call. Will be
1248          * populated when the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#BLOCKED_TYPE}.
1249          * <P>Type: TEXT</P>
1250          */
1251         public static final String CALL_SCREENING_COMPONENT_NAME = "call_screening_component_name";
1252 
1253         /**
1254          * The name of the app which blocked a call. Will be populated when the
1255          * {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#BLOCKED_TYPE}. Provided as a
1256          * convenience so that the call log can still indicate which app blocked a call, even if
1257          * that app is no longer installed.
1258          * <P>Type: TEXT</P>
1259          */
1260         public static final String CALL_SCREENING_APP_NAME = "call_screening_app_name";
1261 
1262         /**
1263          * Where the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#BLOCKED_TYPE},
1264          * indicates the reason why a call is blocked.
1265          * <P>Type: INTEGER</P>
1266          *
1267          * <p>
1268          * Allowed values:
1269          * <ul>
1270          * <li>{@link CallLog.Calls#BLOCK_REASON_NOT_BLOCKED}</li>
1271          * <li>{@link CallLog.Calls#BLOCK_REASON_CALL_SCREENING_SERVICE}</li>
1272          * <li>{@link CallLog.Calls#BLOCK_REASON_DIRECT_TO_VOICEMAIL}</li>
1273          * <li>{@link CallLog.Calls#BLOCK_REASON_BLOCKED_NUMBER}</li>
1274          * <li>{@link CallLog.Calls#BLOCK_REASON_UNKNOWN_NUMBER}</li>
1275          * <li>{@link CallLog.Calls#BLOCK_REASON_RESTRICTED_NUMBER}</li>
1276          * <li>{@link CallLog.Calls#BLOCK_REASON_PAY_PHONE}</li>
1277          * <li>{@link CallLog.Calls#BLOCK_REASON_NOT_IN_CONTACTS}</li>
1278          * </ul>
1279          * </p>
1280          */
1281         public static final String BLOCK_REASON = "block_reason";
1282 
1283         /** @hide */
1284         @LongDef(flag = true, value = {
1285                 MISSED_REASON_NOT_MISSED,
1286                 AUTO_MISSED_EMERGENCY_CALL,
1287                 AUTO_MISSED_MAXIMUM_RINGING,
1288                 AUTO_MISSED_MAXIMUM_DIALING,
1289                 USER_MISSED_NO_ANSWER,
1290                 USER_MISSED_SHORT_RING,
1291                 USER_MISSED_DND_MODE,
1292                 USER_MISSED_LOW_RING_VOLUME,
1293                 USER_MISSED_NO_VIBRATE,
1294                 USER_MISSED_CALL_SCREENING_SERVICE_SILENCED,
1295                 USER_MISSED_CALL_FILTERS_TIMEOUT,
1296                 USER_MISSED_NEVER_RANG
1297         })
1298         @Retention(RetentionPolicy.SOURCE)
1299         public @interface MissedReason {}
1300 
1301         /**
1302          * Value for {@link CallLog.Calls#MISSED_REASON}, set as the default value when a call was
1303          * not missed.
1304          */
1305         public static final long MISSED_REASON_NOT_MISSED = 0;
1306 
1307         /**
1308          * Value for {@link CallLog.Calls#MISSED_REASON}, set when {@link CallLog.Calls#TYPE} is
1309          * {@link CallLog.Calls#MISSED_TYPE} to indicate that a call was automatically rejected by
1310          * system because an ongoing emergency call.
1311          */
1312         public static final long AUTO_MISSED_EMERGENCY_CALL = 1 << 0;
1313 
1314         /**
1315          * Value for {@link CallLog.Calls#MISSED_REASON}, set when {@link CallLog.Calls#TYPE} is
1316          * {@link CallLog.Calls#MISSED_TYPE} to indicate that a call was automatically rejected by
1317          * system because the system cannot support any more ringing calls.
1318          */
1319         public static final long AUTO_MISSED_MAXIMUM_RINGING = 1 << 1;
1320 
1321         /**
1322          * Value for {@link CallLog.Calls#MISSED_REASON}, set when {@link CallLog.Calls#TYPE} is
1323          * {@link CallLog.Calls#MISSED_TYPE} to indicate that a call was automatically rejected by
1324          * system because the system cannot support any more dialing calls.
1325          */
1326         public static final long AUTO_MISSED_MAXIMUM_DIALING = 1 << 2;
1327 
1328         /**
1329          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
1330          * the call was missed just because user didn't answer it.
1331          */
1332         public static final long USER_MISSED_NO_ANSWER = 1 << 16;
1333 
1334         /**
1335          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
1336          * this call rang for a short period of time.
1337          */
1338         public static final long USER_MISSED_SHORT_RING = 1 << 17;
1339 
1340         /**
1341          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, when this call
1342          * rings less than this defined time in millisecond, set
1343          * {@link CallLog.Calls#USER_MISSED_SHORT_RING} bit.
1344          * @hide
1345          */
1346         public static final long SHORT_RING_THRESHOLD = 5000L;
1347 
1348         /**
1349          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
1350          * this call is silenced because the phone is in 'do not disturb mode'.
1351          */
1352         public static final long USER_MISSED_DND_MODE = 1 << 18;
1353 
1354         /**
1355          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
1356          * this call rings with a low ring volume.
1357          */
1358         public static final long USER_MISSED_LOW_RING_VOLUME = 1 << 19;
1359 
1360         /**
1361          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, when this call
1362          * rings in volume less than this defined volume threshold, set
1363          * {@link CallLog.Calls#USER_MISSED_LOW_RING_VOLUME} bit.
1364          * @hide
1365          */
1366         public static final int LOW_RING_VOLUME = 0;
1367 
1368         /**
1369          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE} set this bit when
1370          * this call rings without vibration.
1371          */
1372         public static final long USER_MISSED_NO_VIBRATE = 1 << 20;
1373 
1374         /**
1375          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
1376          * this call is silenced by the call screening service.
1377          */
1378         public static final long USER_MISSED_CALL_SCREENING_SERVICE_SILENCED = 1 << 21;
1379 
1380         /**
1381          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
1382          * the call filters timed out.
1383          */
1384         public static final long USER_MISSED_CALL_FILTERS_TIMEOUT = 1 << 22;
1385 
1386         /**
1387          * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
1388          * the call ended before ringing.
1389          * @hide
1390          */
1391         public static final long USER_MISSED_NEVER_RANG = 1 << 23;
1392 
1393         /**
1394          * Where the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE},
1395          * indicates factors which may have lead the user to miss the call.
1396          * <P>Type: INTEGER</P>
1397          *
1398          * <p>
1399          * There are two main cases. Auto missed cases and user missed cases. Default value is:
1400          * <ul>
1401          * <li>{@link CallLog.Calls#MISSED_REASON_NOT_MISSED}</li>
1402          * </ul>
1403          * </p>
1404          * <P>
1405          * Auto missed cases are those where a call was missed because it was not possible for the
1406          * incoming call to be presented to the user at all. Possible values are:
1407          * <ul>
1408          * <li>{@link CallLog.Calls#AUTO_MISSED_EMERGENCY_CALL}</li>
1409          * <li>{@link CallLog.Calls#AUTO_MISSED_MAXIMUM_RINGING}</li>
1410          * <li>{@link CallLog.Calls#AUTO_MISSED_MAXIMUM_DIALING}</li>
1411          * </ul>
1412          * </P>
1413          * <P>
1414          * User missed cases are those where the incoming call was presented to the user, but
1415          * factors such as a low ringing volume may have contributed to the call being missed.
1416          * Following bits can be set to indicate possible reasons for this:
1417          * <ul>
1418          * <li>{@link CallLog.Calls#USER_MISSED_SHORT_RING}</li>
1419          * <li>{@link CallLog.Calls#USER_MISSED_DND_MODE}</li>
1420          * <li>{@link CallLog.Calls#USER_MISSED_LOW_RING_VOLUME}</li>
1421          * <li>{@link CallLog.Calls#USER_MISSED_NO_VIBRATE}</li>
1422          * <li>{@link CallLog.Calls#USER_MISSED_CALL_SCREENING_SERVICE_SILENCED}</li>
1423          * <li>{@link CallLog.Calls#USER_MISSED_CALL_FILTERS_TIMEOUT}</li>
1424          * </ul>
1425          * </P>
1426          */
1427         public static final String MISSED_REASON = "missed_reason";
1428 
1429         /**
1430          * The subject of the call, as delivered via call composer.
1431          *
1432          * For outgoing calls, contains the subject set by the local user. For incoming calls,
1433          * contains the subject set by the remote caller. May be null if no subject was set.
1434          * <p>Type: TEXT</p>
1435          */
1436         public static final String SUBJECT = "subject";
1437 
1438         /**
1439          * Used as a value in the {@link #PRIORITY} column.
1440          *
1441          * Indicates that the call is of normal priority. This is also the default value for calls
1442          * that did not include call composer elements.
1443          */
1444         public static final int PRIORITY_NORMAL = 0;
1445 
1446         /**
1447          * Used as a value in the {@link #PRIORITY} column.
1448          *
1449          * Indicates that the call is of urgent priority.
1450          */
1451         public static final int PRIORITY_URGENT = 1;
1452 
1453         /**
1454          * The priority of the call, as delivered via call composer.
1455          *
1456          * For outgoing calls, contains the priority set by the local user. For incoming calls,
1457          * contains the priority set by the remote caller. If no priority was set or the call
1458          * did not include call composer elements, defaults to {@link #PRIORITY_NORMAL}.
1459          * Valid values are {@link #PRIORITY_NORMAL} and {@link #PRIORITY_URGENT}.
1460          * <p>Type: INTEGER</p>
1461          */
1462         public static final String PRIORITY = "priority";
1463 
1464         /**
1465          * A reference to the picture that was sent via call composer.
1466          *
1467          * The string contained in this field should be converted to an {@link Uri} via
1468          * {@link Uri#parse(String)}, then passed to {@link ContentResolver#openFileDescriptor}
1469          * in order to obtain a file descriptor to access the picture data.
1470          *
1471          * The user may choose to delete the picture associated with a call independently of the
1472          * call log entry, in which case {@link ContentResolver#openFileDescriptor} may throw a
1473          * {@link FileNotFoundException}.
1474          *
1475          * Note that pictures sent or received via call composer will not be included in any
1476          * backups of the call log.
1477          *
1478          * <p>Type: TEXT</p>
1479          */
1480         public static final String COMPOSER_PHOTO_URI = "composer_photo_uri";
1481 
1482         /**
1483          * A reference to the location that was sent via call composer.
1484          *
1485          * This column contains the content URI of the corresponding entry in {@link Locations}
1486          * table, which contains the actual location data. The
1487          * {@link Manifest.permission#ACCESS_FINE_LOCATION} permission is required to access that
1488          * table.
1489          *
1490          * If your app has the appropriate permissions, the location data may be obtained by
1491          * converting the value of this column to an {@link Uri} via {@link Uri#parse}, then passing
1492          * the result to {@link ContentResolver#query}.
1493          *
1494          * The user may choose to delete the location associated with a call independently of the
1495          * call log entry, in which case the {@link Cursor} returned from
1496          * {@link ContentResolver#query} will either be {@code null} or empty, with
1497          * {@link Cursor#getCount()} returning {@code 0}.
1498          *
1499          * This column will not be populated when a call is received while the device is locked, and
1500          * it will not be part of any backups.
1501          *
1502          * <p>Type: TEXT</p>
1503          */
1504         public static final String LOCATION = "location";
1505 
1506         /**
1507          * A reference to indicate whether phone account migration process is pending.
1508          *
1509          * Before Android 13, {@link PhoneAccountHandle#getId()} returns the ICCID for Telephony
1510          * PhoneAccountHandle. Starting from Android 13, {@link PhoneAccountHandle#getId()} returns
1511          * the Subscription ID for Telephony PhoneAccountHandle. A phone account migration process
1512          * is to ensure this PhoneAccountHandle migration process cross the Android versions in
1513          * the CallLog database.
1514          *
1515          * <p>Type: INTEGER</p>
1516          * @hide
1517          */
1518         public static final String IS_PHONE_ACCOUNT_MIGRATION_PENDING =
1519                 "is_call_log_phone_account_migration_pending";
1520 
1521         /**
1522          * Adds a call to the call log.
1523          *
1524          * @param ci the CallerInfo object to get the target contact from.  Can be null
1525          * if the contact is unknown.
1526          * @param context the context used to get the ContentResolver
1527          * @param number the phone number to be added to the calls db
1528          * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which
1529          *        is set by the network and denotes the number presenting rules for
1530          *        "allowed", "payphone", "restricted" or "unknown"
1531          * @param callType enumerated values for "incoming", "outgoing", or "missed"
1532          * @param features features of the call (e.g. Video).
1533          * @param accountHandle The accountHandle object identifying the provider of the call
1534          * @param start time stamp for the call in milliseconds
1535          * @param duration call duration in seconds
1536          * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for
1537          *                  the call.
1538          * @param isPhoneAccountMigrationPending whether the PhoneAccountHandle ID need to migrate
1539          * @result The URI of the call log entry belonging to the user that made or received this
1540          *        call.
1541          * {@hide}
1542          */
addCall(CallerInfo ci, Context context, String number, int presentation, int callType, int features, PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage, long missedReason, int isPhoneAccountMigrationPending)1543         public static Uri addCall(CallerInfo ci, Context context, String number,
1544                 int presentation, int callType, int features,
1545                 PhoneAccountHandle accountHandle,
1546                 long start, int duration, Long dataUsage, long missedReason,
1547                 int isPhoneAccountMigrationPending) {
1548             return addCall(ci, context, number, "" /* postDialDigits */, "" /* viaNumber */,
1549                 presentation, callType, features, accountHandle, start, duration,
1550                 dataUsage, false /* addForAllUsers */, null /* userToBeInsertedTo */,
1551                 false /* isRead */, Calls.BLOCK_REASON_NOT_BLOCKED /* callBlockReason */,
1552                 null /* callScreeningAppName */, null /* callScreeningComponentName */,
1553                     missedReason, isPhoneAccountMigrationPending);
1554         }
1555 
1556 
1557         /**
1558          * Adds a call to the call log.
1559          *
1560          * @param ci the CallerInfo object to get the target contact from.  Can be null
1561          * if the contact is unknown.
1562          * @param context the context used to get the ContentResolver
1563          * @param number the phone number to be added to the calls db
1564          * @param viaNumber the secondary number that the incoming call received with. If the
1565          *       call was received with the SIM assigned number, then this field must be ''.
1566          * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which
1567          *        is set by the network and denotes the number presenting rules for
1568          *        "allowed", "payphone", "restricted" or "unknown"
1569          * @param callType enumerated values for "incoming", "outgoing", or "missed"
1570          * @param features features of the call (e.g. Video).
1571          * @param accountHandle The accountHandle object identifying the provider of the call
1572          * @param start time stamp for the call in milliseconds
1573          * @param duration call duration in seconds
1574          * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for
1575          *                  the call.
1576          * @param addForAllUsers If true, the call is added to the call log of all currently
1577          *        running users. The caller must have the MANAGE_USERS permission if this is true.
1578          * @param userToBeInsertedTo {@link UserHandle} of user that the call is going to be
1579          *                           inserted to. null if it is inserted to the current user. The
1580          *                           value is ignored if @{link addForAllUsers} is true.
1581          * @param isPhoneAccountMigrationPending whether the PhoneAccountHandle ID need to migrate
1582          * @result The URI of the call log entry belonging to the user that made or received this
1583          *        call.
1584          * {@hide}
1585          */
addCall(CallerInfo ci, Context context, String number, String postDialDigits, String viaNumber, int presentation, int callType, int features, PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo, long missedReason, int isPhoneAccountMigrationPending)1586         public static Uri addCall(CallerInfo ci, Context context, String number,
1587                 String postDialDigits, String viaNumber, int presentation, int callType,
1588                 int features, PhoneAccountHandle accountHandle, long start, int duration,
1589                 Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
1590                 long missedReason, int isPhoneAccountMigrationPending) {
1591             return addCall(ci, context, number, postDialDigits, viaNumber, presentation, callType,
1592                 features, accountHandle, start, duration, dataUsage, addForAllUsers,
1593                 userToBeInsertedTo, false /* isRead */ , Calls.BLOCK_REASON_NOT_BLOCKED
1594                 /* callBlockReason */, null /* callScreeningAppName */,
1595                 null /* callScreeningComponentName */, missedReason,
1596                 isPhoneAccountMigrationPending);
1597         }
1598 
1599 
1600         /**
1601          * Adds a call to the call log.
1602          *
1603          * @param ci the CallerInfo object to get the target contact from.  Can be null
1604          * if the contact is unknown.
1605          * @param context the context used to get the ContentResolver
1606          * @param number the phone number to be added to the calls db
1607          * @param postDialDigits the post-dial digits that were dialed after the number,
1608          *        if it was outgoing. Otherwise it is ''.
1609          * @param viaNumber the secondary number that the incoming call received with. If the
1610          *        call was received with the SIM assigned number, then this field must be ''.
1611          * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which
1612          *        is set by the network and denotes the number presenting rules for
1613          *        "allowed", "payphone", "restricted" or "unknown"
1614          * @param callType enumerated values for "incoming", "outgoing", or "missed"
1615          * @param features features of the call (e.g. Video).
1616          * @param accountHandle The accountHandle object identifying the provider of the call
1617          * @param start time stamp for the call in milliseconds
1618          * @param duration call duration in seconds
1619          * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for
1620          *                  the call.
1621          * @param addForAllUsers If true, the call is added to the call log of all currently
1622          *        running users. The caller must have the MANAGE_USERS permission if this is true.
1623          * @param userToBeInsertedTo {@link UserHandle} of user that the call is going to be
1624          *                           inserted to. null if it is inserted to the current user. The
1625          *                           value is ignored if @{link addForAllUsers} is true.
1626          * @param isRead Flag to show if the missed call log has been read by the user or not.
1627          *                Used for call log restore of missed calls.
1628          * @param callBlockReason The reason why the call is blocked.
1629          * @param callScreeningAppName The call screening application name which block the call.
1630          * @param callScreeningComponentName The call screening component name which block the call.
1631          * @param missedReason The encoded missed information of the call.
1632          * @param isPhoneAccountMigrationPending whether the PhoneAccountHandle ID need to migrate
1633          *
1634          * @result The URI of the call log entry belonging to the user that made or received this
1635          *        call.  This could be of the shadow provider.  Do not return it to non-system apps,
1636          *        as they don't have permissions.
1637          * {@hide}
1638          */
1639         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
addCall(CallerInfo ci, Context context, String number, String postDialDigits, String viaNumber, int presentation, int callType, int features, PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo, boolean isRead, int callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName, long missedReason, int isPhoneAccountMigrationPending)1640         public static Uri addCall(CallerInfo ci, Context context, String number,
1641                 String postDialDigits, String viaNumber, int presentation, int callType,
1642                 int features, PhoneAccountHandle accountHandle, long start, int duration,
1643                 Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
1644                 boolean isRead, int callBlockReason, CharSequence callScreeningAppName,
1645                 String callScreeningComponentName, long missedReason,
1646                 int isPhoneAccountMigrationPending) {
1647             AddCallParams.AddCallParametersBuilder builder =
1648                     new AddCallParams.AddCallParametersBuilder();
1649             builder.setCallerInfo(ci);
1650             builder.setNumber(number);
1651             builder.setPostDialDigits(postDialDigits);
1652             builder.setViaNumber(viaNumber);
1653             builder.setPresentation(presentation);
1654             builder.setCallType(callType);
1655             builder.setFeatures(features);
1656             builder.setAccountHandle(accountHandle);
1657             builder.setStart(start);
1658             builder.setDuration(duration);
1659             builder.setDataUsage(dataUsage == null ? Long.MIN_VALUE : dataUsage);
1660             builder.setAddForAllUsers(addForAllUsers);
1661             builder.setUserToBeInsertedTo(userToBeInsertedTo);
1662             builder.setIsRead(isRead);
1663             builder.setCallBlockReason(callBlockReason);
1664             builder.setCallScreeningAppName(callScreeningAppName);
1665             builder.setCallScreeningComponentName(callScreeningComponentName);
1666             builder.setMissedReason(missedReason);
1667             builder.setIsPhoneAccountMigrationPending(isPhoneAccountMigrationPending);
1668 
1669             return addCall(context, builder.build());
1670         }
1671 
1672         /**
1673          * Adds a call to the call log, using the provided parameters
1674          * @result The URI of the call log entry belonging to the user that made or received this
1675          *        call.  This could be of the shadow provider.  Do not return it to non-system apps,
1676          *        as they don't have permissions.
1677          * @hide
1678          */
addCall( @onNull Context context, @NonNull AddCallParams params)1679         public static @NonNull Uri addCall(
1680                 @NonNull Context context, @NonNull AddCallParams params) {
1681             if (VERBOSE_LOG) {
1682                 Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s",
1683                         params.mNumber, params.mUserToBeInsertedTo, params.mAddForAllUsers));
1684             }
1685             final ContentResolver resolver = context.getContentResolver();
1686 
1687             String accountAddress = getLogAccountAddress(context, params.mAccountHandle);
1688 
1689             int numberPresentation = getLogNumberPresentation(params.mNumber, params.mPresentation);
1690             String name = (params.mCallerInfo != null) ? params.mCallerInfo.getName() : "";
1691             if (numberPresentation != PRESENTATION_ALLOWED) {
1692                 params.mNumber = "";
1693                 if (params.mCallerInfo != null) {
1694                     name = "";
1695                 }
1696             }
1697 
1698             // accountHandle information
1699             String accountComponentString = null;
1700             String accountId = null;
1701             if (params.mAccountHandle != null) {
1702                 accountComponentString = params.mAccountHandle.getComponentName().flattenToString();
1703                 accountId = params.mAccountHandle.getId();
1704             }
1705 
1706             ContentValues values = new ContentValues(14);
1707 
1708             values.put(NUMBER, params.mNumber);
1709             values.put(POST_DIAL_DIGITS, params.mPostDialDigits);
1710             values.put(VIA_NUMBER, params.mViaNumber);
1711             values.put(NUMBER_PRESENTATION, Integer.valueOf(numberPresentation));
1712             values.put(TYPE, Integer.valueOf(params.mCallType));
1713             values.put(FEATURES, params.mFeatures);
1714             values.put(DATE, Long.valueOf(params.mStart));
1715             values.put(DURATION, Long.valueOf(params.mDuration));
1716             if (params.mDataUsage != Long.MIN_VALUE) {
1717                 values.put(DATA_USAGE, params.mDataUsage);
1718             }
1719             values.put(PHONE_ACCOUNT_COMPONENT_NAME, accountComponentString);
1720             values.put(PHONE_ACCOUNT_ID, accountId);
1721             values.put(PHONE_ACCOUNT_ADDRESS, accountAddress);
1722             values.put(NEW, Integer.valueOf(1));
1723             values.put(CACHED_NAME, name);
1724             values.put(ADD_FOR_ALL_USERS, params.mAddForAllUsers ? 1 : 0);
1725 
1726             if (params.mCallType == MISSED_TYPE) {
1727                 values.put(IS_READ, Integer.valueOf(params.mIsRead ? 1 : 0));
1728             }
1729 
1730             values.put(BLOCK_REASON, params.mCallBlockReason);
1731             values.put(CALL_SCREENING_APP_NAME, charSequenceToString(params.mCallScreeningAppName));
1732             values.put(CALL_SCREENING_COMPONENT_NAME, params.mCallScreeningComponentName);
1733             values.put(MISSED_REASON, Long.valueOf(params.mMissedReason));
1734             values.put(PRIORITY, params.mPriority);
1735             values.put(SUBJECT, params.mSubject);
1736             if (params.mPictureUri != null) {
1737                 values.put(COMPOSER_PHOTO_URI, params.mPictureUri.toString());
1738             }
1739             values.put(IS_PHONE_ACCOUNT_MIGRATION_PENDING, params.mIsPhoneAccountMigrationPending);
1740 
1741             if ((params.mCallerInfo != null) && (params.mCallerInfo.getContactId() > 0)) {
1742                 // Update usage information for the number associated with the contact ID.
1743                 // We need to use both the number and the ID for obtaining a data ID since other
1744                 // contacts may have the same number.
1745 
1746                 final Cursor cursor;
1747 
1748                 // We should prefer normalized one (probably coming from
1749                 // Phone.NORMALIZED_NUMBER column) first. If it isn't available try others.
1750                 if (params.mCallerInfo.normalizedNumber != null) {
1751                     final String normalizedPhoneNumber = params.mCallerInfo.normalizedNumber;
1752                     cursor = resolver.query(Phone.CONTENT_URI,
1753                             new String[] { Phone._ID },
1754                             Phone.CONTACT_ID + " =? AND " + Phone.NORMALIZED_NUMBER + " =?",
1755                             new String[] { String.valueOf(params.mCallerInfo.getContactId()),
1756                                     normalizedPhoneNumber},
1757                             null);
1758                 } else {
1759                     final String phoneNumber = params.mCallerInfo.getPhoneNumber() != null
1760                             ? params.mCallerInfo.getPhoneNumber() : params.mNumber;
1761                     cursor = resolver.query(
1762                             Uri.withAppendedPath(Callable.CONTENT_FILTER_URI,
1763                                     Uri.encode(phoneNumber)),
1764                             new String[] { Phone._ID },
1765                             Phone.CONTACT_ID + " =?",
1766                             new String[] { String.valueOf(params.mCallerInfo.getContactId()) },
1767                             null);
1768                 }
1769 
1770                 if (cursor != null) {
1771                     try {
1772                         if (cursor.getCount() > 0 && cursor.moveToFirst()) {
1773                             final String dataId = cursor.getString(0);
1774                             updateDataUsageStatForData(resolver, dataId);
1775                             if (params.mDuration >= MIN_DURATION_FOR_NORMALIZED_NUMBER_UPDATE_MS
1776                                     && params.mCallType == Calls.OUTGOING_TYPE
1777                                     && TextUtils.isEmpty(params.mCallerInfo.normalizedNumber)) {
1778                                 updateNormalizedNumber(context, resolver, dataId, params.mNumber);
1779                             }
1780                         }
1781                     } finally {
1782                         cursor.close();
1783                     }
1784                 }
1785             }
1786 
1787             /*
1788                 Writing the calllog works in the following way:
1789                 - All user entries
1790                     - if user-0 is encrypted, insert to user-0's shadow only.
1791                       (other users should also be encrypted, so nothing to do for other users.)
1792                     - if user-0 is decrypted, insert to user-0's real provider, as well as
1793                       all other users that are running and decrypted and should have calllog.
1794 
1795                 - Single user entry.
1796                     - If the target user is encryted, insert to its shadow.
1797                     - Otherwise insert to its real provider.
1798 
1799                 When the (real) calllog provider starts, it copies entries that it missed from
1800                 elsewhere.
1801                 - When user-0's (real) provider starts, it copies from user-0's shadow, and clears
1802                   the shadow.
1803 
1804                 - When other users (real) providers start, unless it shouldn't have calllog entries,
1805                      - Copy from the user's shadow, and clears the shadow.
1806                      - Copy from user-0's entries that are FOR_ALL_USERS = 1.  (and don't clear it.)
1807              */
1808 
1809             Uri result = null;
1810 
1811             final UserManager userManager = context.getSystemService(UserManager.class);
1812             final int currentUserId = userManager.getProcessUserId();
1813 
1814             if (params.mAddForAllUsers) {
1815                 if (userManager.isUserUnlocked(UserHandle.SYSTEM)) {
1816                     // If the user is unlocked, insert to the location provider if a location is
1817                     // provided. Do not store location if the device is still locked -- this
1818                     // puts it into device-encrypted storage instead of credential-encrypted
1819                     // storage.
1820                     Uri locationUri = maybeInsertLocation(params, resolver, UserHandle.SYSTEM);
1821                     if (locationUri != null) {
1822                         values.put(Calls.LOCATION, locationUri.toString());
1823                     }
1824                 }
1825 
1826                 // First, insert to the system user.
1827                 final Uri uriForSystem = addEntryAndRemoveExpiredEntries(
1828                         context, userManager, UserHandle.SYSTEM, values);
1829                 if (uriForSystem == null
1830                         || SHADOW_AUTHORITY.equals(uriForSystem.getAuthority())) {
1831                     // This means the system user is still encrypted and the entry has inserted
1832                     // into the shadow.  This means other users are still all encrypted.
1833                     // Nothing further to do; just return null.
1834                     return null;
1835                 }
1836                 if (UserHandle.USER_SYSTEM == currentUserId) {
1837                     result = uriForSystem;
1838                 }
1839 
1840                 // Otherwise, insert to all other users that are running and unlocked.
1841 
1842                 final List<UserInfo> users = userManager.getAliveUsers();
1843 
1844                 final int count = users.size();
1845                 for (int i = 0; i < count; i++) {
1846                     final UserInfo userInfo = users.get(i);
1847                     final UserHandle userHandle = userInfo.getUserHandle();
1848                     final int userId = userHandle.getIdentifier();
1849 
1850                     if (userHandle.isSystem()) {
1851                         // Already written.
1852                         continue;
1853                     }
1854 
1855                     if (!shouldHaveSharedCallLogEntries(context, userManager, userId)) {
1856                         // Shouldn't have calllog entries.
1857                         continue;
1858                     }
1859 
1860                     // For other users, we write only when they're running *and* decrypted.
1861                     // Other providers will copy from the system user's real provider, when they
1862                     // start.
1863                     if (userManager.isUserRunning(userHandle)
1864                             && userManager.isUserUnlocked(userHandle)) {
1865                         Uri locationUri = maybeInsertLocation(params, resolver, userHandle);
1866                         if (locationUri != null) {
1867                             values.put(Calls.LOCATION, locationUri.toString());
1868                         } else {
1869                             values.put(Calls.LOCATION, (String) null);
1870                         }
1871                         final Uri uri = addEntryAndRemoveExpiredEntries(context, userManager,
1872                                 userHandle, values);
1873                         if (userId == currentUserId) {
1874                             result = uri;
1875                         }
1876                     }
1877                 }
1878             } else {
1879                 // Single-user entry. Just write to that user, assuming it's running.  If the
1880                 // user is encrypted, we write to the shadow calllog.
1881                 final UserHandle targetUserHandle = params.mUserToBeInsertedTo != null
1882                         ? params.mUserToBeInsertedTo
1883                         : UserHandle.of(currentUserId);
1884 
1885                 if (userManager.isUserRunning(targetUserHandle)
1886                         && userManager.isUserUnlocked(targetUserHandle)) {
1887                     Uri locationUri = maybeInsertLocation(params, resolver, targetUserHandle);
1888                     if (locationUri != null) {
1889                         values.put(Calls.LOCATION, locationUri.toString());
1890                     } else {
1891                         values.put(Calls.LOCATION, (String) null);
1892                     }
1893                 }
1894 
1895                 result = addEntryAndRemoveExpiredEntries(context, userManager, targetUserHandle,
1896                         values);
1897             }
1898             return result;
1899         }
1900 
charSequenceToString(CharSequence sequence)1901         private static String charSequenceToString(CharSequence sequence) {
1902             return sequence == null ? null : sequence.toString();
1903         }
1904 
1905         /** @hide */
shouldHaveSharedCallLogEntries(Context context, UserManager userManager, int userId)1906         public static boolean shouldHaveSharedCallLogEntries(Context context,
1907                 UserManager userManager, int userId) {
1908             if (userManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
1909                     UserHandle.of(userId))) {
1910                 return false;
1911             }
1912             final UserInfo userInfo = userManager.getUserInfo(userId);
1913             return userInfo != null && !userInfo.isManagedProfile();
1914         }
1915 
1916         /**
1917          * Query the call log database for the last dialed number.
1918          * @param context Used to get the content resolver.
1919          * @return The last phone number dialed (outgoing) or an empty
1920          * string if none exist yet.
1921          */
getLastOutgoingCall(Context context)1922         public static String getLastOutgoingCall(Context context) {
1923             final ContentResolver resolver = context.getContentResolver();
1924             Cursor c = null;
1925             try {
1926                 c = resolver.query(
1927                     CONTENT_URI_LIMIT_1,
1928                     new String[] {NUMBER},
1929                     TYPE + " = " + OUTGOING_TYPE,
1930                     null,
1931                     DEFAULT_SORT_ORDER);
1932                 if (c == null || !c.moveToFirst()) {
1933                     return "";
1934                 }
1935                 return c.getString(0);
1936             } finally {
1937                 if (c != null) c.close();
1938             }
1939         }
1940 
addEntryAndRemoveExpiredEntries(Context context, UserManager userManager, UserHandle user, ContentValues values)1941         private static Uri addEntryAndRemoveExpiredEntries(Context context, UserManager userManager,
1942                 UserHandle user, ContentValues values) {
1943             final ContentResolver resolver = context.getContentResolver();
1944 
1945             // Since we're doing this operation on behalf of an app, we only
1946             // want to use the actual "unlocked" state.
1947             final Uri uri = ContentProvider.maybeAddUserId(
1948                     userManager.isUserUnlocked(user) ? CONTENT_URI : SHADOW_CONTENT_URI,
1949                     user.getIdentifier());
1950 
1951             if (VERBOSE_LOG) {
1952                 Log.v(LOG_TAG, String.format("Inserting to %s", uri));
1953             }
1954 
1955             try {
1956                 // When cleaning up the call log, try to delete older call long entries on a per
1957                 // PhoneAccount basis first.  There can be multiple ConnectionServices causing
1958                 // the addition of entries in the call log.  With the introduction of Self-Managed
1959                 // ConnectionServices, we want to ensure that a misbehaving self-managed CS cannot
1960                 // spam the call log with its own entries, causing entries from Telephony to be
1961                 // removed.
1962                 final Uri result = resolver.insert(uri, values);
1963                 if (result != null) {
1964                     String lastPathSegment = result.getLastPathSegment();
1965                     // When inserting into the call log, if ContentProvider#insert detect an appops
1966                     // denial a non-null "silent rejection" URI is returned which ends in 0.
1967                     // Example: content://call_log/calls/0
1968                     // The 0 in the last part of the path indicates a fake call id of 0.
1969                     // A denial when logging calls from the platform is bad; there is no other
1970                     // logging to indicate that this has happened so we will check for that scenario
1971                     // here and log a warning so we have a hint as to what is going on.
1972                     if (lastPathSegment != null && lastPathSegment.equals("0")) {
1973                         Log.w(LOG_TAG, "Failed to insert into call log due to appops denial;"
1974                                 + " resultUri=" + result);
1975                     }
1976                 } else {
1977                     Log.w(LOG_TAG, "Failed to insert into call log; null result uri.");
1978                 }
1979 
1980                 if (values.containsKey(PHONE_ACCOUNT_ID)
1981                         && !TextUtils.isEmpty(values.getAsString(PHONE_ACCOUNT_ID))
1982                         && values.containsKey(PHONE_ACCOUNT_COMPONENT_NAME)
1983                         && !TextUtils.isEmpty(values.getAsString(PHONE_ACCOUNT_COMPONENT_NAME))) {
1984                     // Only purge entries for the same phone account.
1985                     resolver.delete(uri, "_id IN " +
1986                             "(SELECT _id FROM calls"
1987                             + " WHERE " + PHONE_ACCOUNT_COMPONENT_NAME + " = ?"
1988                             + " AND " + PHONE_ACCOUNT_ID + " = ?"
1989                             + " ORDER BY " + DEFAULT_SORT_ORDER
1990                             + " LIMIT -1 OFFSET 500)", new String[] {
1991                             values.getAsString(PHONE_ACCOUNT_COMPONENT_NAME),
1992                             values.getAsString(PHONE_ACCOUNT_ID)
1993                     });
1994                 } else {
1995                     // No valid phone account specified, so default to the old behavior.
1996                     resolver.delete(uri, "_id IN " +
1997                             "(SELECT _id FROM calls ORDER BY " + DEFAULT_SORT_ORDER
1998                             + " LIMIT -1 OFFSET 500)", null);
1999                 }
2000 
2001                 return result;
2002             } catch (IllegalArgumentException e) {
2003                 Log.w(LOG_TAG, "Failed to insert calllog", e);
2004                 // Even though we make sure the target user is running and decrypted before calling
2005                 // this method, there's a chance that the user just got shut down, in which case
2006                 // we'll still get "IllegalArgumentException: Unknown URL content://call_log/calls".
2007                 return null;
2008             }
2009         }
2010 
maybeInsertLocation(AddCallParams params, ContentResolver resolver, UserHandle user)2011         private static Uri maybeInsertLocation(AddCallParams params, ContentResolver resolver,
2012                 UserHandle user) {
2013             if (Double.isNaN(params.mLatitude) || Double.isNaN(params.mLongitude)) {
2014                 return null;
2015             }
2016             ContentValues locationValues = new ContentValues();
2017             locationValues.put(Locations.LATITUDE, params.mLatitude);
2018             locationValues.put(Locations.LONGITUDE, params.mLongitude);
2019             Uri locationUri = ContentProvider.maybeAddUserId(Locations.CONTENT_URI,
2020                     user.getIdentifier());
2021             try {
2022                 return resolver.insert(locationUri, locationValues);
2023             } catch (SecurityException e) {
2024                 // This can happen if the caller doesn't have location permissions. If that's the
2025                 // case just skip the insertion.
2026                 Log.w(LOG_TAG, "Skipping inserting location because caller lacks"
2027                         + " ACCESS_FINE_LOCATION.");
2028                 return null;
2029             }
2030         }
2031 
updateDataUsageStatForData(ContentResolver resolver, String dataId)2032         private static void updateDataUsageStatForData(ContentResolver resolver, String dataId) {
2033             final Uri feedbackUri = DataUsageFeedback.FEEDBACK_URI.buildUpon()
2034                     .appendPath(dataId)
2035                     .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
2036                                 DataUsageFeedback.USAGE_TYPE_CALL)
2037                     .build();
2038             resolver.update(feedbackUri, new ContentValues(), null, null);
2039         }
2040 
2041         /*
2042          * Update the normalized phone number for the given dataId in the ContactsProvider, based
2043          * on the user's current country.
2044          */
updateNormalizedNumber(Context context, ContentResolver resolver, String dataId, String number)2045         private static void updateNormalizedNumber(Context context, ContentResolver resolver,
2046                 String dataId, String number) {
2047             if (TextUtils.isEmpty(number) || TextUtils.isEmpty(dataId)) {
2048                 return;
2049             }
2050             final String countryIso = getCurrentCountryIso(context);
2051             if (TextUtils.isEmpty(countryIso)) {
2052                 return;
2053             }
2054             final String normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso);
2055             if (TextUtils.isEmpty(normalizedNumber)) {
2056                 return;
2057             }
2058             final ContentValues values = new ContentValues();
2059             values.put(Phone.NORMALIZED_NUMBER, normalizedNumber);
2060             resolver.update(Data.CONTENT_URI, values, Data._ID + "=?", new String[] {dataId});
2061         }
2062 
2063         /**
2064          * Remap network specified number presentation types
2065          * TelecomManager.PRESENTATION_xxx to calllog number presentation types
2066          * Calls.PRESENTATION_xxx, in order to insulate the persistent calllog
2067          * from any future radio changes.
2068          * If the number field is empty set the presentation type to Unknown.
2069          */
getLogNumberPresentation(String number, int presentation)2070         private static int getLogNumberPresentation(String number, int presentation) {
2071             if (presentation == TelecomManager.PRESENTATION_RESTRICTED) {
2072                 return presentation;
2073             }
2074 
2075             if (presentation == TelecomManager.PRESENTATION_PAYPHONE) {
2076                 return presentation;
2077             }
2078 
2079             if (presentation == TelecomManager.PRESENTATION_UNAVAILABLE) {
2080                 return PRESENTATION_UNAVAILABLE;
2081             }
2082 
2083             if (TextUtils.isEmpty(number)
2084                     || presentation == TelecomManager.PRESENTATION_UNKNOWN) {
2085                 return PRESENTATION_UNKNOWN;
2086             }
2087 
2088             return PRESENTATION_ALLOWED;
2089         }
2090 
getLogAccountAddress(Context context, PhoneAccountHandle accountHandle)2091         private static String getLogAccountAddress(Context context,
2092                 PhoneAccountHandle accountHandle) {
2093             TelecomManager tm = null;
2094             try {
2095                 tm = TelecomManager.from(context);
2096             } catch (UnsupportedOperationException e) {
2097                 if (VERBOSE_LOG) {
2098                     Log.v(LOG_TAG, "No TelecomManager found to get account address.");
2099                 }
2100             }
2101 
2102             String accountAddress = null;
2103             if (tm != null && accountHandle != null) {
2104                 PhoneAccount account = tm.getPhoneAccount(accountHandle);
2105                 if (account != null) {
2106                     Uri address = account.getSubscriptionAddress();
2107                     if (address != null) {
2108                         accountAddress = address.getSchemeSpecificPart();
2109                     }
2110                 }
2111             }
2112             return accountAddress;
2113         }
2114 
getCurrentCountryIso(Context context)2115         private static String getCurrentCountryIso(Context context) {
2116             String countryIso = null;
2117             final CountryDetector detector = (CountryDetector) context.getSystemService(
2118                     Context.COUNTRY_DETECTOR);
2119             if (detector != null) {
2120                 final Country country = detector.detectCountry();
2121                 if (country != null) {
2122                     countryIso = country.getCountryIso();
2123                 }
2124             }
2125             return countryIso;
2126         }
2127 
2128         /**
2129          * Check if the missedReason code indicate that the call was user missed or automatically
2130          * rejected by system.
2131          *
2132          * @param missedReason
2133          * The result is true if the call was user missed, false if the call was automatically
2134          * rejected by system.
2135          *
2136          * @hide
2137          */
isUserMissed(long missedReason)2138         public static boolean isUserMissed(long missedReason) {
2139             return missedReason >= (USER_MISSED_NO_ANSWER);
2140         }
2141     }
2142 
2143     /**
2144      * Table that contains information on location data sent via call composer.
2145      *
2146      * All fields in this table require the {@link Manifest.permission#ACCESS_FINE_LOCATION}
2147      * permission for access.
2148      */
2149     public static class Locations implements BaseColumns {
Locations()2150         private Locations() {}
2151         /**
2152          * Authority for the locations content provider.
2153          */
2154         public static final String AUTHORITY = "call_composer_locations";
2155 
2156         /**
2157          * Content type for the location table.
2158          */
2159         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_composer_location";
2160 
2161         /**
2162          * Content type for the location entries.
2163          */
2164         public static final String CONTENT_ITEM_TYPE =
2165                 "vnd.android.cursor.item/call_composer_location";
2166 
2167         /**
2168          * The content URI for this table
2169          */
2170         @NonNull
2171         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
2172 
2173         /**
2174          * Latitude in degrees. See {@link android.location.Location#setLatitude(double)}.
2175          * <p>Type: REAL</p>
2176          */
2177         public static final String LATITUDE = "latitude";
2178 
2179         /**
2180          * Longitude in degrees. See {@link android.location.Location#setLongitude(double)}.
2181          * <p>Type: REAL</p>
2182          */
2183         public static final String LONGITUDE = "longitude";
2184     }
2185 }
2186