Home | History | Annotate | Download | only in provider
      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.annotation.UnsupportedAppUsage;
     21 import android.content.ContentProvider;
     22 import android.content.ContentResolver;
     23 import android.content.ContentValues;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.pm.UserInfo;
     27 import android.database.Cursor;
     28 import android.location.Country;
     29 import android.location.CountryDetector;
     30 import android.net.Uri;
     31 import android.os.Build;
     32 import android.os.UserHandle;
     33 import android.os.UserManager;
     34 import android.provider.ContactsContract.CommonDataKinds.Callable;
     35 import android.provider.ContactsContract.CommonDataKinds.Phone;
     36 import android.provider.ContactsContract.Data;
     37 import android.provider.ContactsContract.DataUsageFeedback;
     38 import android.telecom.PhoneAccount;
     39 import android.telecom.PhoneAccountHandle;
     40 import android.telecom.TelecomManager;
     41 import android.telephony.PhoneNumberUtils;
     42 import android.text.TextUtils;
     43 import android.util.Log;
     44 
     45 import com.android.internal.telephony.CallerInfo;
     46 import com.android.internal.telephony.PhoneConstants;
     47 
     48 import java.util.List;
     49 
     50 /**
     51  * The CallLog provider contains information about placed and received calls.
     52  */
     53 public class CallLog {
     54     private static final String LOG_TAG = "CallLog";
     55     private static final boolean VERBOSE_LOG = false; // DON'T SUBMIT WITH TRUE.
     56 
     57     public static final String AUTHORITY = "call_log";
     58 
     59     /**
     60      * The content:// style URL for this provider
     61      */
     62     public static final Uri CONTENT_URI =
     63         Uri.parse("content://" + AUTHORITY);
     64 
     65 
     66     /**
     67      * The "shadow" provider stores calllog when the real calllog provider is encrypted.  The
     68      * real provider will alter copy from it when it starts, and remove the entries in the shadow.
     69      *
     70      * <p>See the comment in {@link Calls#addCall} for the details.
     71      *
     72      * @hide
     73      */
     74     public static final String SHADOW_AUTHORITY = "call_log_shadow";
     75 
     76     /**
     77      * Contains the recent calls.
     78      */
     79     public static class Calls implements BaseColumns {
     80         /**
     81          * The content:// style URL for this table
     82          */
     83         public static final Uri CONTENT_URI =
     84                 Uri.parse("content://call_log/calls");
     85 
     86         /** @hide */
     87         public static final Uri SHADOW_CONTENT_URI =
     88                 Uri.parse("content://call_log_shadow/calls");
     89 
     90         /**
     91          * The content:// style URL for filtering this table on phone numbers
     92          */
     93         public static final Uri CONTENT_FILTER_URI =
     94                 Uri.parse("content://call_log/calls/filter");
     95 
     96         /**
     97          * Query parameter used to limit the number of call logs returned.
     98          * <p>
     99          * TYPE: integer
    100          */
    101         public static final String LIMIT_PARAM_KEY = "limit";
    102 
    103         /**
    104          * Query parameter used to specify the starting record to return.
    105          * <p>
    106          * TYPE: integer
    107          */
    108         public static final String OFFSET_PARAM_KEY = "offset";
    109 
    110         /**
    111          * An optional URI parameter which instructs the provider to allow the operation to be
    112          * applied to voicemail records as well.
    113          * <p>
    114          * TYPE: Boolean
    115          * <p>
    116          * Using this parameter with a value of {@code true} will result in a security error if the
    117          * calling package does not have appropriate permissions to access voicemails.
    118          *
    119          * @hide
    120          */
    121         public static final String ALLOW_VOICEMAILS_PARAM_KEY = "allow_voicemails";
    122 
    123         /**
    124          * An optional extra used with {@link #CONTENT_TYPE Calls.CONTENT_TYPE} and
    125          * {@link Intent#ACTION_VIEW} to specify that the presented list of calls should be
    126          * filtered for a particular call type.
    127          *
    128          * Applications implementing a call log UI should check for this extra, and display a
    129          * filtered list of calls based on the specified call type. If not applicable within the
    130          * application's UI, it should be silently ignored.
    131          *
    132          * <p>
    133          * The following example brings up the call log, showing only missed calls.
    134          * <pre>
    135          * Intent intent = new Intent(Intent.ACTION_VIEW);
    136          * intent.setType(CallLog.Calls.CONTENT_TYPE);
    137          * intent.putExtra(CallLog.Calls.EXTRA_CALL_TYPE_FILTER, CallLog.Calls.MISSED_TYPE);
    138          * startActivity(intent);
    139          * </pre>
    140          * </p>
    141          */
    142         public static final String EXTRA_CALL_TYPE_FILTER =
    143                 "android.provider.extra.CALL_TYPE_FILTER";
    144 
    145         /**
    146          * Content uri used to access call log entries, including voicemail records. You must have
    147          * the READ_CALL_LOG and WRITE_CALL_LOG permissions to read and write to the call log, as
    148          * well as READ_VOICEMAIL and WRITE_VOICEMAIL permissions to read and write voicemails.
    149          */
    150         public static final Uri CONTENT_URI_WITH_VOICEMAIL = CONTENT_URI.buildUpon()
    151                 .appendQueryParameter(ALLOW_VOICEMAILS_PARAM_KEY, "true")
    152                 .build();
    153 
    154         /**
    155          * The default sort order for this table
    156          */
    157         public static final String DEFAULT_SORT_ORDER = "date DESC";
    158 
    159         /**
    160          * The MIME type of {@link #CONTENT_URI} and {@link #CONTENT_FILTER_URI}
    161          * providing a directory of calls.
    162          */
    163         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/calls";
    164 
    165         /**
    166          * The MIME type of a {@link #CONTENT_URI} sub-directory of a single
    167          * call.
    168          */
    169         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls";
    170 
    171         /**
    172          * The type of the call (incoming, outgoing or missed).
    173          * <P>Type: INTEGER (int)</P>
    174          *
    175          * <p>
    176          * Allowed values:
    177          * <ul>
    178          * <li>{@link #INCOMING_TYPE}</li>
    179          * <li>{@link #OUTGOING_TYPE}</li>
    180          * <li>{@link #MISSED_TYPE}</li>
    181          * <li>{@link #VOICEMAIL_TYPE}</li>
    182          * <li>{@link #REJECTED_TYPE}</li>
    183          * <li>{@link #BLOCKED_TYPE}</li>
    184          * <li>{@link #ANSWERED_EXTERNALLY_TYPE}</li>
    185          * </ul>
    186          * </p>
    187          */
    188         public static final String TYPE = "type";
    189 
    190         /** Call log type for incoming calls. */
    191         public static final int INCOMING_TYPE = 1;
    192         /** Call log type for outgoing calls. */
    193         public static final int OUTGOING_TYPE = 2;
    194         /** Call log type for missed calls. */
    195         public static final int MISSED_TYPE = 3;
    196         /** Call log type for voicemails. */
    197         public static final int VOICEMAIL_TYPE = 4;
    198         /** Call log type for calls rejected by direct user action. */
    199         public static final int REJECTED_TYPE = 5;
    200         /** Call log type for calls blocked automatically. */
    201         public static final int BLOCKED_TYPE = 6;
    202         /**
    203          * Call log type for a call which was answered on another device.  Used in situations where
    204          * a call rings on multiple devices simultaneously and it ended up being answered on a
    205          * device other than the current one.
    206          */
    207         public static final int ANSWERED_EXTERNALLY_TYPE = 7;
    208 
    209         /**
    210          * Bit-mask describing features of the call (e.g. video).
    211          *
    212          * <P>Type: INTEGER (int)</P>
    213          */
    214         public static final String FEATURES = "features";
    215 
    216         /** Call had video. */
    217         public static final int FEATURES_VIDEO = 1 << 0;
    218 
    219         /** Call was pulled externally. */
    220         public static final int FEATURES_PULLED_EXTERNALLY = 1 << 1;
    221 
    222         /** Call was HD. */
    223         public static final int FEATURES_HD_CALL = 1 << 2;
    224 
    225         /** Call was WIFI call. */
    226         public static final int FEATURES_WIFI = 1 << 3;
    227 
    228         /**
    229          * Indicates the call underwent Assisted Dialing.
    230          * @hide
    231          */
    232         public static final int FEATURES_ASSISTED_DIALING_USED = 1 << 4;
    233 
    234         /** Call was on RTT at some point */
    235         public static final int FEATURES_RTT = 1 << 5;
    236 
    237         /**
    238          * The phone number as the user entered it.
    239          * <P>Type: TEXT</P>
    240          */
    241         public static final String NUMBER = "number";
    242 
    243         /**
    244          * The number presenting rules set by the network.
    245          *
    246          * <p>
    247          * Allowed values:
    248          * <ul>
    249          * <li>{@link #PRESENTATION_ALLOWED}</li>
    250          * <li>{@link #PRESENTATION_RESTRICTED}</li>
    251          * <li>{@link #PRESENTATION_UNKNOWN}</li>
    252          * <li>{@link #PRESENTATION_PAYPHONE}</li>
    253          * </ul>
    254          * </p>
    255          *
    256          * <P>Type: INTEGER</P>
    257          */
    258         public static final String NUMBER_PRESENTATION = "presentation";
    259 
    260         /** Number is allowed to display for caller id. */
    261         public static final int PRESENTATION_ALLOWED = 1;
    262         /** Number is blocked by user. */
    263         public static final int PRESENTATION_RESTRICTED = 2;
    264         /** Number is not specified or unknown by network. */
    265         public static final int PRESENTATION_UNKNOWN = 3;
    266         /** Number is a pay phone. */
    267         public static final int PRESENTATION_PAYPHONE = 4;
    268 
    269         /**
    270          * The ISO 3166-1 two letters country code of the country where the
    271          * user received or made the call.
    272          * <P>
    273          * Type: TEXT
    274          * </P>
    275          */
    276         public static final String COUNTRY_ISO = "countryiso";
    277 
    278         /**
    279          * The date the call occured, in milliseconds since the epoch
    280          * <P>Type: INTEGER (long)</P>
    281          */
    282         public static final String DATE = "date";
    283 
    284         /**
    285          * The duration of the call in seconds
    286          * <P>Type: INTEGER (long)</P>
    287          */
    288         public static final String DURATION = "duration";
    289 
    290         /**
    291          * The data usage of the call in bytes.
    292          * <P>Type: INTEGER (long)</P>
    293          */
    294         public static final String DATA_USAGE = "data_usage";
    295 
    296         /**
    297          * Whether or not the call has been acknowledged
    298          * <P>Type: INTEGER (boolean)</P>
    299          */
    300         public static final String NEW = "new";
    301 
    302         /**
    303          * The cached name associated with the phone number, if it exists.
    304          *
    305          * <p>This value is typically filled in by the dialer app for the caching purpose,
    306          * so it's not guaranteed to be present, and may not be current if the contact
    307          * information associated with this number has changed.
    308          * <P>Type: TEXT</P>
    309          */
    310         public static final String CACHED_NAME = "name";
    311 
    312         /**
    313          * The cached number type (Home, Work, etc) associated with the
    314          * phone number, if it exists.
    315          *
    316          * <p>This value is typically filled in by the dialer app for the caching purpose,
    317          * so it's not guaranteed to be present, and may not be current if the contact
    318          * information associated with this number has changed.
    319          * <P>Type: INTEGER</P>
    320          */
    321         public static final String CACHED_NUMBER_TYPE = "numbertype";
    322 
    323         /**
    324          * The cached number label, for a custom number type, associated with the
    325          * phone number, if it exists.
    326          *
    327          * <p>This value is typically filled in by the dialer app for the caching purpose,
    328          * so it's not guaranteed to be present, and may not be current if the contact
    329          * information associated with this number has changed.
    330          * <P>Type: TEXT</P>
    331          */
    332         public static final String CACHED_NUMBER_LABEL = "numberlabel";
    333 
    334         /**
    335          * URI of the voicemail entry. Populated only for {@link #VOICEMAIL_TYPE}.
    336          * <P>Type: TEXT</P>
    337          */
    338         public static final String VOICEMAIL_URI = "voicemail_uri";
    339 
    340         /**
    341          * Transcription of the call or voicemail entry. This will only be populated for call log
    342          * entries of type {@link #VOICEMAIL_TYPE} that have valid transcriptions.
    343          */
    344         public static final String TRANSCRIPTION = "transcription";
    345 
    346         /**
    347          * State of voicemail transcription entry. This will only be populated for call log
    348          * entries of type {@link #VOICEMAIL_TYPE}.
    349          * @hide
    350          */
    351         public static final String TRANSCRIPTION_STATE = "transcription_state";
    352 
    353         /**
    354          * Whether this item has been read or otherwise consumed by the user.
    355          * <p>
    356          * Unlike the {@link #NEW} field, which requires the user to have acknowledged the
    357          * existence of the entry, this implies the user has interacted with the entry.
    358          * <P>Type: INTEGER (boolean)</P>
    359          */
    360         public static final String IS_READ = "is_read";
    361 
    362         /**
    363          * A geocoded location for the number associated with this call.
    364          * <p>
    365          * The string represents a city, state, or country associated with the number.
    366          * <P>Type: TEXT</P>
    367          */
    368         public static final String GEOCODED_LOCATION = "geocoded_location";
    369 
    370         /**
    371          * The cached URI to look up the contact associated with the phone number, if it exists.
    372          *
    373          * <p>This value is typically filled in by the dialer app for the caching purpose,
    374          * so it's not guaranteed to be present, and may not be current if the contact
    375          * information associated with this number has changed.
    376          * <P>Type: TEXT</P>
    377          */
    378         public static final String CACHED_LOOKUP_URI = "lookup_uri";
    379 
    380         /**
    381          * The cached phone number of the contact which matches this entry, if it exists.
    382          *
    383          * <p>This value is typically filled in by the dialer app for the caching purpose,
    384          * so it's not guaranteed to be present, and may not be current if the contact
    385          * information associated with this number has changed.
    386          * <P>Type: TEXT</P>
    387          */
    388         public static final String CACHED_MATCHED_NUMBER = "matched_number";
    389 
    390         /**
    391          * The cached normalized(E164) version of the phone number, if it exists.
    392          *
    393          * <p>This value is typically filled in by the dialer app for the caching purpose,
    394          * so it's not guaranteed to be present, and may not be current if the contact
    395          * information associated with this number has changed.
    396          * <P>Type: TEXT</P>
    397          */
    398         public static final String CACHED_NORMALIZED_NUMBER = "normalized_number";
    399 
    400         /**
    401          * The cached photo id of the picture associated with the phone number, if it exists.
    402          *
    403          * <p>This value is typically filled in by the dialer app for the caching purpose,
    404          * so it's not guaranteed to be present, and may not be current if the contact
    405          * information associated with this number has changed.
    406          * <P>Type: INTEGER (long)</P>
    407          */
    408         public static final String CACHED_PHOTO_ID = "photo_id";
    409 
    410         /**
    411          * The cached photo URI of the picture associated with the phone number, if it exists.
    412          *
    413          * <p>This value is typically filled in by the dialer app for the caching purpose,
    414          * so it's not guaranteed to be present, and may not be current if the contact
    415          * information associated with this number has changed.
    416          * <P>Type: TEXT (URI)</P>
    417          */
    418         public static final String CACHED_PHOTO_URI = "photo_uri";
    419 
    420         /**
    421          * The cached phone number, formatted with formatting rules based on the country the
    422          * user was in when the call was made or received.
    423          *
    424          * <p>This value is typically filled in by the dialer app for the caching purpose,
    425          * so it's not guaranteed to be present, and may not be current if the contact
    426          * information associated with this number has changed.
    427          * <P>Type: TEXT</P>
    428          */
    429         public static final String CACHED_FORMATTED_NUMBER = "formatted_number";
    430 
    431         // Note: PHONE_ACCOUNT_* constant values are "subscription_*" due to a historic naming
    432         // that was encoded into call log databases.
    433 
    434         /**
    435          * The component name of the account used to place or receive the call; in string form.
    436          * <P>Type: TEXT</P>
    437          */
    438         public static final String PHONE_ACCOUNT_COMPONENT_NAME = "subscription_component_name";
    439 
    440         /**
    441          * The identifier for the account used to place or receive the call.
    442          * <P>Type: TEXT</P>
    443          */
    444         public static final String PHONE_ACCOUNT_ID = "subscription_id";
    445 
    446         /**
    447          * The address associated with the account used to place or receive the call; in string
    448          * form. For SIM-based calls, this is the user's own phone number.
    449          * <P>Type: TEXT</P>
    450          *
    451          * @hide
    452          */
    453         public static final String PHONE_ACCOUNT_ADDRESS = "phone_account_address";
    454 
    455         /**
    456          * Indicates that the entry will be hidden from all queries until the associated
    457          * {@link android.telecom.PhoneAccount} is registered with the system.
    458          * <P>Type: INTEGER</P>
    459          *
    460          * @hide
    461          */
    462         public static final String PHONE_ACCOUNT_HIDDEN = "phone_account_hidden";
    463 
    464         /**
    465          * The subscription ID used to place this call.  This is no longer used and has been
    466          * replaced with PHONE_ACCOUNT_COMPONENT_NAME/PHONE_ACCOUNT_ID.
    467          * For ContactsProvider internal use only.
    468          * <P>Type: INTEGER</P>
    469          *
    470          * @Deprecated
    471          * @hide
    472          */
    473         public static final String SUB_ID = "sub_id";
    474 
    475         /**
    476          * The post-dial portion of a dialed number, including any digits dialed after a
    477          * {@link TelecomManager#DTMF_CHARACTER_PAUSE} or a {@link
    478          * TelecomManager#DTMF_CHARACTER_WAIT} and these characters themselves.
    479          * <P>Type: TEXT</P>
    480          */
    481         public static final String POST_DIAL_DIGITS = "post_dial_digits";
    482 
    483         /**
    484          * For an incoming call, the secondary line number the call was received via.
    485          * When a SIM card has multiple phone numbers associated with it, the via number indicates
    486          * which of the numbers associated with the SIM was called.
    487          */
    488         public static final String VIA_NUMBER = "via_number";
    489 
    490         /**
    491          * Indicates that the entry will be copied from primary user to other users.
    492          * <P>Type: INTEGER</P>
    493          *
    494          * @hide
    495          */
    496         public static final String ADD_FOR_ALL_USERS = "add_for_all_users";
    497 
    498         /**
    499          * The date the row is last inserted, updated, or marked as deleted, in milliseconds
    500          * since the epoch. Read only.
    501          * <P>Type: INTEGER (long)</P>
    502          */
    503         public static final String LAST_MODIFIED = "last_modified";
    504 
    505         /**
    506          * If a successful call is made that is longer than this duration, update the phone number
    507          * in the ContactsProvider with the normalized version of the number, based on the user's
    508          * current country code.
    509          */
    510         private static final int MIN_DURATION_FOR_NORMALIZED_NUMBER_UPDATE_MS = 1000 * 10;
    511 
    512         /**
    513          * Value for {@link CallLog.Calls#BLOCK_REASON}, set as the default value when a call was
    514          * not blocked by a CallScreeningService or any other system call blocking method.
    515          */
    516         public static final int BLOCK_REASON_NOT_BLOCKED = 0;
    517 
    518         /**
    519          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
    520          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked by a
    521          * CallScreeningService. The {@link CallLog.Calls#CALL_SCREENING_COMPONENT_NAME} and
    522          * {@link CallLog.Calls#CALL_SCREENING_APP_NAME} columns will indicate which call screening
    523          * service was responsible for blocking the call.
    524          */
    525         public static final int BLOCK_REASON_CALL_SCREENING_SERVICE = 1;
    526 
    527         /**
    528          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
    529          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
    530          * configured a contact to be sent directly to voicemail.
    531          */
    532         public static final int BLOCK_REASON_DIRECT_TO_VOICEMAIL = 2;
    533 
    534         /**
    535          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
    536          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because it is
    537          * in the BlockedNumbers provider.
    538          */
    539         public static final int BLOCK_REASON_BLOCKED_NUMBER = 3;
    540 
    541         /**
    542          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
    543          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
    544          * has chosen to block all calls from unknown numbers.
    545          */
    546         public static final int BLOCK_REASON_UNKNOWN_NUMBER = 4;
    547 
    548         /**
    549          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
    550          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
    551          * has chosen to block all calls from restricted numbers.
    552          */
    553         public static final int BLOCK_REASON_RESTRICTED_NUMBER = 5;
    554 
    555         /**
    556          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
    557          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
    558          * has chosen to block all calls from pay phones.
    559          */
    560         public static final int BLOCK_REASON_PAY_PHONE = 6;
    561 
    562         /**
    563          * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is
    564          * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user
    565          * has chosen to block all calls from numbers not in their contacts.
    566          */
    567         public static final int BLOCK_REASON_NOT_IN_CONTACTS = 7;
    568 
    569         /**
    570          * The ComponentName of the CallScreeningService which blocked this call. Will be
    571          * populated when the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#BLOCKED_TYPE}.
    572          * <P>Type: TEXT</P>
    573          */
    574         public static final String CALL_SCREENING_COMPONENT_NAME = "call_screening_component_name";
    575 
    576         /**
    577          * The name of the app which blocked a call. Will be populated when the
    578          * {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#BLOCKED_TYPE}. Provided as a
    579          * convenience so that the call log can still indicate which app blocked a call, even if
    580          * that app is no longer installed.
    581          * <P>Type: TEXT</P>
    582          */
    583         public static final String CALL_SCREENING_APP_NAME = "call_screening_app_name";
    584 
    585         /**
    586          * Where the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#BLOCKED_TYPE},
    587          * indicates the reason why a call is blocked.
    588          * <P>Type: INTEGER</P>
    589          *
    590          * <p>
    591          * Allowed values:
    592          * <ul>
    593          * <li>{@link CallLog.Calls#BLOCK_REASON_NOT_BLOCKED}</li>
    594          * <li>{@link CallLog.Calls#BLOCK_REASON_CALL_SCREENING_SERVICE}</li>
    595          * <li>{@link CallLog.Calls#BLOCK_REASON_DIRECT_TO_VOICEMAIL}</li>
    596          * <li>{@link CallLog.Calls#BLOCK_REASON_BLOCKED_NUMBER}</li>
    597          * <li>{@link CallLog.Calls#BLOCK_REASON_UNKNOWN_NUMBER}</li>
    598          * <li>{@link CallLog.Calls#BLOCK_REASON_RESTRICTED_NUMBER}</li>
    599          * <li>{@link CallLog.Calls#BLOCK_REASON_PAY_PHONE}</li>
    600          * <li>{@link CallLog.Calls#BLOCK_REASON_NOT_IN_CONTACTS}</li>
    601          * </ul>
    602          * </p>
    603          */
    604         public static final String BLOCK_REASON = "block_reason";
    605 
    606         /**
    607          * Adds a call to the call log.
    608          *
    609          * @param ci the CallerInfo object to get the target contact from.  Can be null
    610          * if the contact is unknown.
    611          * @param context the context used to get the ContentResolver
    612          * @param number the phone number to be added to the calls db
    613          * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
    614          *        is set by the network and denotes the number presenting rules for
    615          *        "allowed", "payphone", "restricted" or "unknown"
    616          * @param callType enumerated values for "incoming", "outgoing", or "missed"
    617          * @param features features of the call (e.g. Video).
    618          * @param accountHandle The accountHandle object identifying the provider of the call
    619          * @param start time stamp for the call in milliseconds
    620          * @param duration call duration in seconds
    621          * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for
    622          *                  the call.
    623          * @result The URI of the call log entry belonging to the user that made or received this
    624          *        call.
    625          * {@hide}
    626          */
    627         public static Uri addCall(CallerInfo ci, Context context, String number,
    628                 int presentation, int callType, int features,
    629                 PhoneAccountHandle accountHandle,
    630                 long start, int duration, Long dataUsage) {
    631             return addCall(ci, context, number, "" /* postDialDigits */, "" /* viaNumber */,
    632                 presentation, callType, features, accountHandle, start, duration,
    633                 dataUsage, false /* addForAllUsers */, null /* userToBeInsertedTo */,
    634                 false /* isRead */, Calls.BLOCK_REASON_NOT_BLOCKED /* callBlockReason */,
    635                 null /* callScreeningAppName */, null /* callScreeningComponentName */);
    636         }
    637 
    638 
    639         /**
    640          * Adds a call to the call log.
    641          *
    642          * @param ci the CallerInfo object to get the target contact from.  Can be null
    643          * if the contact is unknown.
    644          * @param context the context used to get the ContentResolver
    645          * @param number the phone number to be added to the calls db
    646          * @param viaNumber the secondary number that the incoming call received with. If the
    647          *       call was received with the SIM assigned number, then this field must be ''.
    648          * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
    649          *        is set by the network and denotes the number presenting rules for
    650          *        "allowed", "payphone", "restricted" or "unknown"
    651          * @param callType enumerated values for "incoming", "outgoing", or "missed"
    652          * @param features features of the call (e.g. Video).
    653          * @param accountHandle The accountHandle object identifying the provider of the call
    654          * @param start time stamp for the call in milliseconds
    655          * @param duration call duration in seconds
    656          * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for
    657          *                  the call.
    658          * @param addForAllUsers If true, the call is added to the call log of all currently
    659          *        running users. The caller must have the MANAGE_USERS permission if this is true.
    660          * @param userToBeInsertedTo {@link UserHandle} of user that the call is going to be
    661          *                           inserted to. null if it is inserted to the current user. The
    662          *                           value is ignored if @{link addForAllUsers} is true.
    663          * @result The URI of the call log entry belonging to the user that made or received this
    664          *        call.
    665          * {@hide}
    666          */
    667         public static Uri addCall(CallerInfo ci, Context context, String number,
    668                 String postDialDigits, String viaNumber, int presentation, int callType,
    669                 int features, PhoneAccountHandle accountHandle, long start, int duration,
    670                 Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo) {
    671             return addCall(ci, context, number, postDialDigits, viaNumber, presentation, callType,
    672                 features, accountHandle, start, duration, dataUsage, addForAllUsers,
    673                 userToBeInsertedTo, false /* isRead */ , Calls.BLOCK_REASON_NOT_BLOCKED
    674                 /* callBlockReason */, null /* callScreeningAppName */,
    675                 null /* callScreeningComponentName */);
    676         }
    677 
    678         /**
    679          * Adds a call to the call log.
    680          *
    681          * @param ci the CallerInfo object to get the target contact from.  Can be null
    682          * if the contact is unknown.
    683          * @param context the context used to get the ContentResolver
    684          * @param number the phone number to be added to the calls db
    685          * @param postDialDigits the post-dial digits that were dialed after the number,
    686          *        if it was outgoing. Otherwise it is ''.
    687          * @param viaNumber the secondary number that the incoming call received with. If the
    688          *        call was received with the SIM assigned number, then this field must be ''.
    689          * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
    690          *        is set by the network and denotes the number presenting rules for
    691          *        "allowed", "payphone", "restricted" or "unknown"
    692          * @param callType enumerated values for "incoming", "outgoing", or "missed"
    693          * @param features features of the call (e.g. Video).
    694          * @param accountHandle The accountHandle object identifying the provider of the call
    695          * @param start time stamp for the call in milliseconds
    696          * @param duration call duration in seconds
    697          * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for
    698          *                  the call.
    699          * @param addForAllUsers If true, the call is added to the call log of all currently
    700          *        running users. The caller must have the MANAGE_USERS permission if this is true.
    701          * @param userToBeInsertedTo {@link UserHandle} of user that the call is going to be
    702          *                           inserted to. null if it is inserted to the current user. The
    703          *                           value is ignored if @{link addForAllUsers} is true.
    704          * @param isRead Flag to show if the missed call log has been read by the user or not.
    705          *                Used for call log restore of missed calls.
    706          * @param callBlockReason The reason why the call is blocked.
    707          * @param callScreeningAppName The call screening application name which block the call.
    708          * @param callScreeningComponentName The call screening component name which block the call.
    709          *
    710          * @result The URI of the call log entry belonging to the user that made or received this
    711          *        call.  This could be of the shadow provider.  Do not return it to non-system apps,
    712          *        as they don't have permissions.
    713          * {@hide}
    714          */
    715         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    716         public static Uri addCall(CallerInfo ci, Context context, String number,
    717                 String postDialDigits, String viaNumber, int presentation, int callType,
    718                 int features, PhoneAccountHandle accountHandle, long start, int duration,
    719                 Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
    720                 boolean isRead, int callBlockReason, CharSequence callScreeningAppName,
    721                 String callScreeningComponentName) {
    722             if (VERBOSE_LOG) {
    723                 Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s",
    724                         number, userToBeInsertedTo, addForAllUsers));
    725             }
    726             final ContentResolver resolver = context.getContentResolver();
    727 
    728             String accountAddress = getLogAccountAddress(context, accountHandle);
    729 
    730             int numberPresentation = getLogNumberPresentation(number, presentation);
    731             if (numberPresentation != PRESENTATION_ALLOWED) {
    732                 number = "";
    733                 if (ci != null) {
    734                     ci.name = "";
    735                 }
    736             }
    737 
    738             // accountHandle information
    739             String accountComponentString = null;
    740             String accountId = null;
    741             if (accountHandle != null) {
    742                 accountComponentString = accountHandle.getComponentName().flattenToString();
    743                 accountId = accountHandle.getId();
    744             }
    745 
    746             ContentValues values = new ContentValues(6);
    747 
    748             values.put(NUMBER, number);
    749             values.put(POST_DIAL_DIGITS, postDialDigits);
    750             values.put(VIA_NUMBER, viaNumber);
    751             values.put(NUMBER_PRESENTATION, Integer.valueOf(numberPresentation));
    752             values.put(TYPE, Integer.valueOf(callType));
    753             values.put(FEATURES, features);
    754             values.put(DATE, Long.valueOf(start));
    755             values.put(DURATION, Long.valueOf(duration));
    756             if (dataUsage != null) {
    757                 values.put(DATA_USAGE, dataUsage);
    758             }
    759             values.put(PHONE_ACCOUNT_COMPONENT_NAME, accountComponentString);
    760             values.put(PHONE_ACCOUNT_ID, accountId);
    761             values.put(PHONE_ACCOUNT_ADDRESS, accountAddress);
    762             values.put(NEW, Integer.valueOf(1));
    763             if ((ci != null) && (ci.name != null)) {
    764                 values.put(CACHED_NAME, ci.name);
    765             }
    766             values.put(ADD_FOR_ALL_USERS, addForAllUsers ? 1 : 0);
    767 
    768             if (callType == MISSED_TYPE) {
    769                 values.put(IS_READ, Integer.valueOf(isRead ? 1 : 0));
    770             }
    771 
    772             values.put(BLOCK_REASON, callBlockReason);
    773             values.put(CALL_SCREENING_APP_NAME, charSequenceToString(callScreeningAppName));
    774             values.put(CALL_SCREENING_COMPONENT_NAME, callScreeningComponentName);
    775 
    776             if ((ci != null) && (ci.contactIdOrZero > 0)) {
    777                 // Update usage information for the number associated with the contact ID.
    778                 // We need to use both the number and the ID for obtaining a data ID since other
    779                 // contacts may have the same number.
    780 
    781                 final Cursor cursor;
    782 
    783                 // We should prefer normalized one (probably coming from
    784                 // Phone.NORMALIZED_NUMBER column) first. If it isn't available try others.
    785                 if (ci.normalizedNumber != null) {
    786                     final String normalizedPhoneNumber = ci.normalizedNumber;
    787                     cursor = resolver.query(Phone.CONTENT_URI,
    788                             new String[] { Phone._ID },
    789                             Phone.CONTACT_ID + " =? AND " + Phone.NORMALIZED_NUMBER + " =?",
    790                             new String[] { String.valueOf(ci.contactIdOrZero),
    791                                     normalizedPhoneNumber},
    792                             null);
    793                 } else {
    794                     final String phoneNumber = ci.phoneNumber != null ? ci.phoneNumber : number;
    795                     cursor = resolver.query(
    796                             Uri.withAppendedPath(Callable.CONTENT_FILTER_URI,
    797                                     Uri.encode(phoneNumber)),
    798                             new String[] { Phone._ID },
    799                             Phone.CONTACT_ID + " =?",
    800                             new String[] { String.valueOf(ci.contactIdOrZero) },
    801                             null);
    802                 }
    803 
    804                 if (cursor != null) {
    805                     try {
    806                         if (cursor.getCount() > 0 && cursor.moveToFirst()) {
    807                             final String dataId = cursor.getString(0);
    808                             updateDataUsageStatForData(resolver, dataId);
    809                             if (duration >= MIN_DURATION_FOR_NORMALIZED_NUMBER_UPDATE_MS
    810                                     && callType == Calls.OUTGOING_TYPE
    811                                     && TextUtils.isEmpty(ci.normalizedNumber)) {
    812                                 updateNormalizedNumber(context, resolver, dataId, number);
    813                             }
    814                         }
    815                     } finally {
    816                         cursor.close();
    817                     }
    818                 }
    819             }
    820 
    821             /*
    822                 Writing the calllog works in the following way:
    823                 - All user entries
    824                     - if user-0 is encrypted, insert to user-0's shadow only.
    825                       (other users should also be encrypted, so nothing to do for other users.)
    826                     - if user-0 is decrypted, insert to user-0's real provider, as well as
    827                       all other users that are running and decrypted and should have calllog.
    828 
    829                 - Single user entry.
    830                     - If the target user is encryted, insert to its shadow.
    831                     - Otherwise insert to its real provider.
    832 
    833                 When the (real) calllog provider starts, it copies entries that it missed from
    834                 elsewhere.
    835                 - When user-0's (real) provider starts, it copies from user-0's shadow, and clears
    836                   the shadow.
    837 
    838                 - When other users (real) providers start, unless it shouldn't have calllog entries,
    839                      - Copy from the user's shadow, and clears the shadow.
    840                      - Copy from user-0's entries that are FOR_ALL_USERS = 1.  (and don't clear it.)
    841              */
    842 
    843             Uri result = null;
    844 
    845             final UserManager userManager = context.getSystemService(UserManager.class);
    846             final int currentUserId = userManager.getUserHandle();
    847 
    848             if (addForAllUsers) {
    849                 // First, insert to the system user.
    850                 final Uri uriForSystem = addEntryAndRemoveExpiredEntries(
    851                         context, userManager, UserHandle.SYSTEM, values);
    852                 if (uriForSystem == null
    853                         || SHADOW_AUTHORITY.equals(uriForSystem.getAuthority())) {
    854                     // This means the system user is still encrypted and the entry has inserted
    855                     // into the shadow.  This means other users are still all encrypted.
    856                     // Nothing further to do; just return null.
    857                     return null;
    858                 }
    859                 if (UserHandle.USER_SYSTEM == currentUserId) {
    860                     result = uriForSystem;
    861                 }
    862 
    863                 // Otherwise, insert to all other users that are running and unlocked.
    864 
    865                 final List<UserInfo> users = userManager.getUsers(true);
    866 
    867                 final int count = users.size();
    868                 for (int i = 0; i < count; i++) {
    869                     final UserInfo userInfo = users.get(i);
    870                     final UserHandle userHandle = userInfo.getUserHandle();
    871                     final int userId = userHandle.getIdentifier();
    872 
    873                     if (userHandle.isSystem()) {
    874                         // Already written.
    875                         continue;
    876                     }
    877 
    878                     if (!shouldHaveSharedCallLogEntries(context, userManager, userId)) {
    879                         // Shouldn't have calllog entries.
    880                         continue;
    881                     }
    882 
    883                     // For other users, we write only when they're running *and* decrypted.
    884                     // Other providers will copy from the system user's real provider, when they
    885                     // start.
    886                     if (userManager.isUserRunning(userHandle)
    887                             && userManager.isUserUnlocked(userHandle)) {
    888                         final Uri uri = addEntryAndRemoveExpiredEntries(context, userManager,
    889                                 userHandle, values);
    890                         if (userId == currentUserId) {
    891                             result = uri;
    892                         }
    893                     }
    894                 }
    895             } else {
    896                 // Single-user entry. Just write to that user, assuming it's running.  If the
    897                 // user is encrypted, we write to the shadow calllog.
    898 
    899                 final UserHandle targetUserHandle = userToBeInsertedTo != null
    900                         ? userToBeInsertedTo
    901                         : UserHandle.of(currentUserId);
    902                 result = addEntryAndRemoveExpiredEntries(context, userManager, targetUserHandle,
    903                         values);
    904             }
    905             return result;
    906         }
    907 
    908         private static String charSequenceToString(CharSequence sequence) {
    909             return sequence == null ? null : sequence.toString();
    910         }
    911 
    912         /** @hide */
    913         public static boolean shouldHaveSharedCallLogEntries(Context context,
    914                 UserManager userManager, int userId) {
    915             if (userManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
    916                     UserHandle.of(userId))) {
    917                 return false;
    918             }
    919             final UserInfo userInfo = userManager.getUserInfo(userId);
    920             return userInfo != null && !userInfo.isManagedProfile();
    921         }
    922 
    923         /**
    924          * Query the call log database for the last dialed number.
    925          * @param context Used to get the content resolver.
    926          * @return The last phone number dialed (outgoing) or an empty
    927          * string if none exist yet.
    928          */
    929         public static String getLastOutgoingCall(Context context) {
    930             final ContentResolver resolver = context.getContentResolver();
    931             Cursor c = null;
    932             try {
    933                 c = resolver.query(
    934                     CONTENT_URI,
    935                     new String[] {NUMBER},
    936                     TYPE + " = " + OUTGOING_TYPE,
    937                     null,
    938                     DEFAULT_SORT_ORDER + " LIMIT 1");
    939                 if (c == null || !c.moveToFirst()) {
    940                     return "";
    941                 }
    942                 return c.getString(0);
    943             } finally {
    944                 if (c != null) c.close();
    945             }
    946         }
    947 
    948         private static Uri addEntryAndRemoveExpiredEntries(Context context, UserManager userManager,
    949                 UserHandle user, ContentValues values) {
    950             final ContentResolver resolver = context.getContentResolver();
    951 
    952             // Since we're doing this operation on behalf of an app, we only
    953             // want to use the actual "unlocked" state.
    954             final Uri uri = ContentProvider.maybeAddUserId(
    955                     userManager.isUserUnlocked(user) ? CONTENT_URI : SHADOW_CONTENT_URI,
    956                     user.getIdentifier());
    957 
    958             if (VERBOSE_LOG) {
    959                 Log.v(LOG_TAG, String.format("Inserting to %s", uri));
    960             }
    961 
    962             try {
    963                 // When cleaning up the call log, try to delete older call long entries on a per
    964                 // PhoneAccount basis first.  There can be multiple ConnectionServices causing
    965                 // the addition of entries in the call log.  With the introduction of Self-Managed
    966                 // ConnectionServices, we want to ensure that a misbehaving self-managed CS cannot
    967                 // spam the call log with its own entries, causing entries from Telephony to be
    968                 // removed.
    969                 final Uri result = resolver.insert(uri, values);
    970                 if (values.containsKey(PHONE_ACCOUNT_ID)
    971                         && !TextUtils.isEmpty(values.getAsString(PHONE_ACCOUNT_ID))
    972                         && values.containsKey(PHONE_ACCOUNT_COMPONENT_NAME)
    973                         && !TextUtils.isEmpty(values.getAsString(PHONE_ACCOUNT_COMPONENT_NAME))) {
    974                     // Only purge entries for the same phone account.
    975                     resolver.delete(uri, "_id IN " +
    976                             "(SELECT _id FROM calls"
    977                             + " WHERE " + PHONE_ACCOUNT_COMPONENT_NAME + " = ?"
    978                             + " AND " + PHONE_ACCOUNT_ID + " = ?"
    979                             + " ORDER BY " + DEFAULT_SORT_ORDER
    980                             + " LIMIT -1 OFFSET 500)", new String[] {
    981                             values.getAsString(PHONE_ACCOUNT_COMPONENT_NAME),
    982                             values.getAsString(PHONE_ACCOUNT_ID)
    983                     });
    984                 } else {
    985                     // No valid phone account specified, so default to the old behavior.
    986                     resolver.delete(uri, "_id IN " +
    987                             "(SELECT _id FROM calls ORDER BY " + DEFAULT_SORT_ORDER
    988                             + " LIMIT -1 OFFSET 500)", null);
    989                 }
    990 
    991                 return result;
    992             } catch (IllegalArgumentException e) {
    993                 Log.w(LOG_TAG, "Failed to insert calllog", e);
    994                 // Even though we make sure the target user is running and decrypted before calling
    995                 // this method, there's a chance that the user just got shut down, in which case
    996                 // we'll still get "IllegalArgumentException: Unknown URL content://call_log/calls".
    997                 return null;
    998             }
    999         }
   1000 
   1001         private static void updateDataUsageStatForData(ContentResolver resolver, String dataId) {
   1002             final Uri feedbackUri = DataUsageFeedback.FEEDBACK_URI.buildUpon()
   1003                     .appendPath(dataId)
   1004                     .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
   1005                                 DataUsageFeedback.USAGE_TYPE_CALL)
   1006                     .build();
   1007             resolver.update(feedbackUri, new ContentValues(), null, null);
   1008         }
   1009 
   1010         /*
   1011          * Update the normalized phone number for the given dataId in the ContactsProvider, based
   1012          * on the user's current country.
   1013          */
   1014         private static void updateNormalizedNumber(Context context, ContentResolver resolver,
   1015                 String dataId, String number) {
   1016             if (TextUtils.isEmpty(number) || TextUtils.isEmpty(dataId)) {
   1017                 return;
   1018             }
   1019             final String countryIso = getCurrentCountryIso(context);
   1020             if (TextUtils.isEmpty(countryIso)) {
   1021                 return;
   1022             }
   1023             final String normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso);
   1024             if (TextUtils.isEmpty(normalizedNumber)) {
   1025                 return;
   1026             }
   1027             final ContentValues values = new ContentValues();
   1028             values.put(Phone.NORMALIZED_NUMBER, normalizedNumber);
   1029             resolver.update(Data.CONTENT_URI, values, Data._ID + "=?", new String[] {dataId});
   1030         }
   1031 
   1032         /**
   1033          * Remap network specified number presentation types
   1034          * PhoneConstants.PRESENTATION_xxx to calllog number presentation types
   1035          * Calls.PRESENTATION_xxx, in order to insulate the persistent calllog
   1036          * from any future radio changes.
   1037          * If the number field is empty set the presentation type to Unknown.
   1038          */
   1039         private static int getLogNumberPresentation(String number, int presentation) {
   1040             if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
   1041                 return presentation;
   1042             }
   1043 
   1044             if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
   1045                 return presentation;
   1046             }
   1047 
   1048             if (TextUtils.isEmpty(number)
   1049                     || presentation == PhoneConstants.PRESENTATION_UNKNOWN) {
   1050                 return PRESENTATION_UNKNOWN;
   1051             }
   1052 
   1053             return PRESENTATION_ALLOWED;
   1054         }
   1055 
   1056         private static String getLogAccountAddress(Context context,
   1057                 PhoneAccountHandle accountHandle) {
   1058             TelecomManager tm = null;
   1059             try {
   1060                 tm = TelecomManager.from(context);
   1061             } catch (UnsupportedOperationException e) {
   1062                 if (VERBOSE_LOG) {
   1063                     Log.v(LOG_TAG, "No TelecomManager found to get account address.");
   1064                 }
   1065             }
   1066 
   1067             String accountAddress = null;
   1068             if (tm != null && accountHandle != null) {
   1069                 PhoneAccount account = tm.getPhoneAccount(accountHandle);
   1070                 if (account != null) {
   1071                     Uri address = account.getSubscriptionAddress();
   1072                     if (address != null) {
   1073                         accountAddress = address.getSchemeSpecificPart();
   1074                     }
   1075                 }
   1076             }
   1077             return accountAddress;
   1078         }
   1079 
   1080         private static String getCurrentCountryIso(Context context) {
   1081             String countryIso = null;
   1082             final CountryDetector detector = (CountryDetector) context.getSystemService(
   1083                     Context.COUNTRY_DETECTOR);
   1084             if (detector != null) {
   1085                 final Country country = detector.detectCountry();
   1086                 if (country != null) {
   1087                     countryIso = country.getCountryIso();
   1088                 }
   1089             }
   1090             return countryIso;
   1091         }
   1092     }
   1093 }
   1094