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