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