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