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