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